奇怪的 gulp-uglify 缩小器 'file.isNull()' 在 gulp 构建时出错

strange gulp-uglify minifier 'file.isNull()' error on gulp build

我正在构建一个相对简单的项目来学习 React w/Flux。我正在使用(或尝试使用)Gulp 通过 Browserify、Reactify、Streamify 和 Uglify 创建自动构建,所有这些都是通过 npm 安装的。整个流程都在工作,我做了一些文件更改,重新构建,现在当我 运行 构建时它会因错误而退出。即使在恢复更改并返回到原来的、以前的工作状态之后。我怀疑可能某处发生了权限更改,但我自己还没有这样做,所以我不确定如何进一步诊断(也不确定问题是否存在)。

我应该补充一点,一开始我怀疑是乙烯基流媒体错误导致的问题,但我将 .pipe(buffer())vinyl-buffer 添加到构建流程中,但它并没有改变错误。

这里是gulp:

var gulp = require('gulp');
var uglify = require('gulp-uglify');
var htmlreplace = require('gulp-html-replace');
var source = require('vinyl-source-stream');
var buffer = require('vinyl-buffer');
var browserify = require('browserify');
var watchify = require('watchify');
var reactify = require('reactify');
var streamify = require('gulp-streamify');
var gutil = require('gulp-util');

var path = {
    HTML: 'app/index.html',
    MINIFIED_OUT: 'build.min.js',
    OUT: 'build.js',
    DEST: 'dist',
    DEST_BUILD: 'dist/build',
    DEST_SRC: 'dist/src',
    ENTRY_POINT: './app/App.js'
};

gulp.task('build', function(){
    browserify({
        entries: [path.ENTRY_POINT],
        transform: [reactify]
    })
        .bundle()
        .pipe(uglify().on('error', gutil.log))
        .pipe(source(path.MINIFIED_OUT))
        .pipe(buffer())
        .pipe(streamify(uglify(path.MINIFIED_OUT)))
        .pipe(gulp.dest(path.DEST_BUILD));
});

gulp.task('replaceHTML', function(){
    gulp.src(path.HTML)
        .pipe(htmlreplace({
            'js': 'build/' + path.MINIFIED_OUT
        }))
        .pipe(gulp.dest(path.DEST));
});

gulp.task('production', ['replaceHTML', 'build']);

这里是错误:

[09:54:33] Using gulpfile /Library/WebServer/Documents/lldb/gulpfile.js
[09:54:33] Starting 'replaceHTML'...
[09:54:33] Finished 'replaceHTML' after 8.3 ms
[09:54:33] Starting 'build'...
[09:54:33] Finished 'build' after 27 ms
[09:54:33] Starting 'production'...
[09:54:33] Finished 'production' after 7.07 μs
/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/minifier.js:67
    if (file.isNull()) {
             ^

TypeError: file.isNull is not a function
    at DestroyableTransform.minify [as _transform] (/Library/WebServer    /Documents/lldb/node_modules/gulp-uglify/minifier.js:67:14)
    at DestroyableTransform.Transform._read (/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:10)
    at DestroyableTransform.Transform._write (/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:160:12)
    at doWrite (/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:326:12)
    at writeOrBuffer (/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:312:5)
    at DestroyableTransform.Writable.write (/Library/WebServer/Documents/lldb/node_modules/gulp-uglify/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:239:11)
    at Readable.ondata (/Library/WebServer/Documents/lldb/node_modules/browserify/node_modules/read-only-stream/node_modules/readable-stream/lib/_stream_readable.js:572:20)
    at emitOne (events.js:77:13)
    at Readable.emit (events.js:169:7)
    at readableAddChunk (/Library/WebServer/Documents/lldb/node_modules/browserify/node_modules/read-only-stream/node_modules/readable-stream/lib/_stream_readable.js:195:16)

欢迎提出任何想法 - 谢谢。

好吧,这很奇怪 - 我会 post 让任何人评论 and/or 更新。

按照错误路径,我打开了gulp-uglify下的minifier.js文件。第 67 行(上面的参考错误)显示:

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

    if (file.isStream()) {
      return callback(createError(file, 'Streaming not supported'));
    }

问题是 isNull 和 isStream 不是函数——它们是引用。所以代码需要改成:

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

    if (file.isStream) {
      return callback(createError(file, 'Streaming not supported'));
    }

注意删除了额外的括号 - ()。 returns 这些是它们应该是的引用,而不是 js 试图调用的函数。在我的代码是 运行 和它停止时 运行 之间,额外的 () 如何写入 isNull 和 isStream 是任何人的猜测(并且有点担心) - 我没有进行这些更改。

对于任何感兴趣的人,完整路径说明如下。


isNull 和 isStream 的引用在 index.js 此处:

module.exports = {
  ...
  isStream: require('./lib/isStream'),
  isBuffer: require('./lib/isBuffer'),
  isNull: require('./lib/isNull'),
  ...
};

gulp-uglify -> node_modules -> gulp-util -> lib -> isNull.js (& isStream.js)下引用这个函数,看起来像这样:

module.exports = function(v) {
  return v === null;
};

因此 - 删除 minifier.js 中的函数调用方括号 () 使引用正确并且 gulp 构建运行没有错误。

在一天结束时看起来像是一个 gulp-uglify 问题(我猜)。

Notice the removal of the extra parentheses - (). This returns these to the references they should be, not the functions the js is trying to call. How the extra () got written into isNull and isStream between when my code was running and when it stopped running is anyone's guess (and a little concerning) - I did not make those changes.

它们是引用,是的,但是是对模块中导出的函数的引用。 require('./lib/isNull') returns 该模块的导出; export 是一个函数,所以 isNull 是一个函数。通过删除括号,您现在只检查 file.isNull 是否是永远为真的东西。

但是,无论如何,你看错了东西。这不是 file 的来源。 file 作为参数传递给 minify 函数。所以 file 是一个应该有 isNullisStream 方法的对象。

正在使用 through2 调用 minify 函数,因此如果您的 gulp 文件失败,则可能意味着您做错了什么,可能是顺序错误。不幸的是,错误消息在大多数情况下并没有真正的帮助。

在查看您的 gulp 文件时,我注意到您有两次调用 uglify:

.pipe(uglify().on('error', gutil.log))
…
.pipe(streamify(uglify(path.MINIFIED_OUT)))

第一个看起来不错,也是 gulp-uglify 通常的样子。但是第二个似乎更像是您尝试在那里使用原始 uglify(而不是 gulp-uglify)。这似乎不是一个好主意,因为 uglify 引用了 gulp-uglify,它无论如何都行不通。所以最好删除那行。

我还建议您查看 official recommendation 如何将 browserify 与 uglify 一起使用并修复 uglify() 调用的顺序:您应该在 之后调用它 buffer().

browserify(…)
    .bundle()
    .pipe(source(path.MINIFIED_OUT))
    .pipe(buffer())
    .pipe(uglify())
    .on('error', gutil.log)
    .pipe(gulp.dest(path.DEST_BUILD));