reactjsgulpminifygulp-uglify

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


I'm building a relatively simple project in learning React w/Flux. I'm using (or attempting to use) Gulp to create an automated build with Browserify, Reactify, Streamify, and Uglify, all installed via npm. The whole flow was working, I made a few file changes, rebuilt, and now it is kicking out on error when I run the build. Even after reverting the changes and returning back to the original, previously working state. I'm suspect that perhaps a permission change has occurred somewhere, but I haven't done that myself, so I'm not sure how to diagnose that further (and not certain if the problem is there).

I should add that at first I suspected a vinyl streaming error was the problem, but I added the .pipe(buffer()) and vinyl-buffer into the build flow, however it did not change the error.

Here's 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']);

Here is the error:

[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)

Welcome any ideas - thanks.


Solution

  • 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.

    They are references, yes, but references to functions exported in modules. require('./lib/isNull') returns the export of that module; the export is a function, so isNull is a function. By removing the parentheses, you now only check whether file.isNull is anything which would be always true.

    But, you are looking at the wrong things anyway. That’s not where file comes from. file is being passed as a parameter to the minify function. So file is an object that is supposed to have isNull and isStream methods.

    The minify function is being called with through2, so if your gulp file fails then that likely means that you did something wrong, probably with the order. Unfortunately, the error messages are not really helpful most of the time.

    When looking at your gulpfile, I notice that you have two calls to uglify:

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

    The first one looks fine and is what gulp-uglify usually looks like. But the second seems more like you tried to use the raw uglify (not gulp-uglify) there. That doesn’t seem like a good idea and since uglify is referencing gulp-uglify, it won’t work anyway. So better remove that line.

    I’d also suggest you to look at the official recommendation on how to use browserify with uglify and fix the order of your uglify() call: You should call it after buffer().

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