gpt4 book ai didi

javascript - 自定义 Gulp.js 插件 : TypeError "Path must be a string. Received undefined"

转载 作者:行者123 更新时间:2023-12-03 17:57:53 28 4
gpt4 key购买 nike

我在 StackOverflow 上发现了几个关于 TypeError: Path must be a string 的话题,尽管我无法将建议的解决方案应用到我的案例中。

我正在尝试构建一个连接到(付费)javascriptobfuscator.com 服务的 Gulp 插件,并使用他们的 POST API 来混淆我的 JS。

Gulp 任务如下所示:

var gulp = require('gulp'),
jso = require('./jsobfuscator');

gulp.task('jso', function() {
// .jsx contain extendscript language, which as far as
// the service is concerned, could be treated as .js
return gulp.src('.src/app/jsx/photoshop.jsx')
.pipe(jso())
.pipe(gulp.dest('./dist'))
});

jsobfuscator.js 文件包含以下代码:

var through = require('through2'),
http = require('http'),
gutil = require('gulp-util'),
Readable = require('stream').Readable

module.exports = function() {
/**
* @this {Transform}
*/

var transform = function(file, encoding, callback) {

var that = this;

var proj = {};
proj.APIKey = "/* MyAPIKey*/";
proj.APIPwd = "/* MyAPIPwd*/";
proj.Name = "DoubleUSM";
proj.ReorderCode = true;
proj.ReplaceNames = true;
proj.EncodeStrings = true;
proj.MoveStrings = true;
proj.MoveMembers = true;
proj.DeepObfuscate = true;
proj.SelfCompression = true;
// Unsure about these two...
proj.CompressionRatio = "Auto";
proj.OptimizationMode = "Auto";

var appJS = new Object();
appJS.FileName = "app.js";
appJS.FileCode = file.contents.toString('utf8');
// Will try to implement multiple files later on
proj.Items = [appJS];

var postData = JSON.stringify(proj);

// Length is OK
gutil.log ("Length: " + Buffer.byteLength(postData, 'utf-8'))

var options = {
host: 'service.javascriptobfuscator.com',
path: '/HttpApi.ashx',
method: 'POST',
headers: {
'Content-Type': 'text/json',
'Content-Length': Buffer.byteLength(postData, 'utf-8')
}
};

callback = function(response) {
response.setEncoding('utf8');

var str = '';
response.on('data', function(chunk) {
str += chunk;
});

response.on('end', function() {
// I get the correct response here!
gutil.log(JSON.stringify(JSON.parse(str), null, ' '));

var resObj = JSON.parse(str);
// Converting the received string into a Buffer
var fileStream = new Readable();
// resObj.Items[0].FileCode is where the obfuscated code belongs
fileStream.push(resObj.Items[0].FileCode);
fileStream.push(null);
that.push(fileStream);
callback();
});
}

var req = http.request(options, callback);
req.write(postData);
req.end();
};

return through.obj(transform);
};

当我运行 gulp 任务时,我显然从 javascriptobfuscator 代码得到了正确的响应(如下所示)但是我将文件传递到目的地的部分出现了问题,因为我得到:

(master)*  gulp jso
[15:13:30] Using gulpfile ~/Dropbox/Developer/PROJECTS/DOUBLE USM/gulpfile.js
[15:13:30] Starting 'jso'...
[15:13:31] Lenght: 21897
[15:13:32] {
"Type": "Succeed",
"Items": [
{
"FileName": "app.js",
"FileCode": /* ... Long, horrible, properly obfuscated blob here... */
}
],
"ErrorCode": null,
"Message": null,
"FileName": null,
"LineNumber": null,
"ExceptionToString": null
}
path.js:7
throw new TypeError('Path must be a string. Received ' + inspect(path));
^

TypeError: Path must be a string. Received undefined
at assertPath (path.js:7:11)
at Object.resolve (path.js:1146:7)
at DestroyableTransform.saveFile [as _transform] (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/lib/dest/index.js:36:26)
at DestroyableTransform.Transform._read (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_transform.js:184:10)
at DestroyableTransform.Transform._write (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_transform.js:172:12)
at doWrite (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_writable.js:237:10)
at writeOrBuffer (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_writable.js:227:5)
at DestroyableTransform.Writable.write (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/vinyl-fs/node_modules/readable-stream/lib/_stream_writable.js:194:11)
at DestroyableTransform.ondata (/Users/davidebarranca/Dropbox/Developer/PROJECTS/DOUBLE USM/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:546:20)
at emitOne (events.js:96:13)

不可否认,我不是 Gulp 插件的专家——我正在尝试构建一个供我个人使用的功能。看起来我很接近,但我已经陷入这个死胡同一段时间了,我需要更有经验的人的帮助。

提前致谢


半工作更新

修改response.on('end')回调如下,我终于可以写文件了:

response.on('end', function() {

var resObj = JSON.parse(str);

var fileStream = new Readable();
fileStream.push(resObj.Items[0].FileCode);
fileStream.push(null);

// Manually creating a new Vinyl file
var jsFile = new Vinyl({
cwd: file.cwd,
base: file.base,
path: file.path,
contents: fileStream
});

return that.push(jsFile);
// callback();
});

不过,我必须注释掉最后的 callback(),否则我会遇到指向 response.setEncoding('utf8'); 的错误行,被 response undefined.

现在的问题是,在某种程度上,任务似乎永远不会终止。控制台显示 Starting 'jso'...,文件已写入,控制台返回,但没有 Finished 'jso' after nn ms,最糟糕的是,我完全之后无法链接更多 gulp 任务,所以如果我:

gulp.task('jso1', function() {
return gulp.src('.src/app/jsx/photoshop.jsx')
.pipe(jso())
.pipe(gulp.dest('./dist'))
});

gulp.task('jso2', ['jso1'], function() {
return gulp.src('.src/app/app.js')
.pipe(jso())
.pipe(gulp.dest('./dist'))
});

// then in the Terminal:
$ gulp jso2

我唯一得到的是 jso1 开始,显然工作,但从未完成; jso2 永远不会运行。


最佳答案

许多小时的摸索让我找到了答案。简单地说,在我的 Gulp 插件中:

  1. 我必须在 response.on('end') 回调中返回一个新的 Vinyl 文件:文件的 contents 属性需要成为来自服务器响应的流。
  2. 我的半成品解决方案的主要缺陷是我为两个截然不同的函数指定了相同的名称 (callback)。一个是来自初始 transform 函数的 callback;另一个是 http.request 回调。注释掉最后一个 callback() 调用,在 return that.push(jsFile); 之后阻止整个 Gulp 任务结束。

完整的工作代码如下:

var through  = require('through2'),
http = require('http'),
gutil = require('gulp-util'),
Readable = require('stream').Readable,
Vinyl = require('vinyl');

module.exports = function() {

var transform = function(file, encoding, callback) {

if (file.isNull()) { return callback(null, file) }

var that = this;

var proj = {};
proj.APIKey = "/* MyAPIKey */";
proj.APIPwd = "/* APIPwd */";
proj.Name = "Project";
proj.ReorderCode = true;
proj.ReplaceNames = true;
proj.EncodeStrings = true;
proj.MoveStrings = true;
proj.MoveMembers = true;
proj.DeepObfuscate = true;
proj.SelfCompression = true;
proj.CompressionRatio = "Auto";
proj.OptimizationMode = "Auto";

var appJS = new Object();
appJS.FileName = "app.js";
appJS.FileCode = file.contents.toString('utf8');

proj.Items = [appJS];

var postData = JSON.stringify(proj);

var options = {
host: 'service.javascriptobfuscator.com',
path: '/HttpApi.ashx',
method: 'POST',
headers: {
'Content-Type': 'text/json',
'Content-Length': Buffer.byteLength(postData, 'utf-8')
}
};

/* Renamed to avoid confusion with transform's callback */
postCallback = function(response) {

response.setEncoding('utf8');
var str = '';
response.on('data', function(chunk) {
str += chunk;
});

response.on('end', function() {

var resObj = JSON.parse(str);
var fileStream = new Readable();
fileStream.push(resObj.Items[0].FileCode);
fileStream.push(null);

/* Return a new Vinyl File */
var jsFile = new Vinyl({
cwd: file.cwd,
base: file.base,
path: file.path,
contents: fileStream
});

that.push(jsFile);
callback();
});
}

var req = http.request(options, postCallback);
req.write(postData);
req.end();

};

return through.obj(transform);
};

也许有更好的方法可以在不创建新文件的情况下返回 Vinyl 文件。

另一个改进是将所有源文件分组并对 javascriptobfuscator API 进行一次 http 调用(实际上可以将多个文件添加到 proj.Items 数组),但我有不知道如何在源代码中对文件进行分组,一次将它们全部传递给 Gulp 插件,然后再将它们拆分回来。

关于javascript - 自定义 Gulp.js 插件 : TypeError "Path must be a string. Received undefined",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42161864/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com