Search code examples
javascriptbrowserifybundling-and-minificationconditional-compilationuglifyjs

Browserify, minifyify, conditional compilation


TL;DR

minifyify (the Browserify plugin) makes use of uglify-js but appears to be unable to handle Conditional compilation:

  • compression works
  • uglifyjs alone works for conditional compilation
  • minifyify provides additional compilation optimization but I have been unable to use conditional compilation with it

I'm using Browserify with the babelify transformer and the minifyify plugin. Here is the cmd, broken down in readable parts:

browserify src/scripts/app/index.js -o build/prod/public/assets/js/appBundle.min.js -t [ babelify --presets [ es2015 ] ] -p [ minifyify --no-map --uglify [ --compress [ --drop_console --dead_code --conditionals --unused --if_return ] --mangle --screw-ie8 --define [ DEBUG=false ] ] ]

I've gotten every setting/option to work. However, I am unable to get conditional compilation to work. Minifyify uses uglifyjs' minify method. The fact I'm passing by minifyify shouldn't really change anything.

Building directly through uglifyjs works

uglifyjs input.js --compress --dead_code --define DEBUG=false -o output.js

But then I lose the additional compressions/optimizations provided by minifyify.

I'm also open to another build process. My needs are resumed in the settings of the current process:

  • CommonJS required modules
  • transpiling of ES6 to ES5
  • advanced minification/compression

Solution

  • It turns out that the culprit was, more or less, uglifyjs. The property name for global definition in the task is different between CMD and Programmatic API.

    • cmd line: --define VARNAME=VALUE
    • programmatic: compress: {global_defs: { varname: value } }

    That being said, it also seems that minifyify or browserify isn't passing the cmd-line options properly for global definitions - we're still investigating this

    programmatic solution

    By using the Browserify & minifyify programmatic API, the build task works. Below is the same task as the one in OP, but it works:

    "use strict";
    var browserify = require("browserify"),
        fs = require("fs");
    
    browserify("src/scripts/app/index.js")
        .transform("babelify", {presets: ["es2015"], plugins: ["transform-object-assign"]})
        .plugin("minifyify", {map: false, uglify: {
            compress: {
                drop_console: true,
                dead_code: true,
                conditionals: true,
                unused: true,
                if_return: true,
                global_defs: {
                    DEBUG: false
                }
            },
            mangle: true,
            "screw-ie8": true
        }})
        .bundle()
        .pipe(fs.createWriteStream("build/prod/public/assets/js/appBundle.js"));
    

    update in uglifyjs docs

    I've proposed a modification to the current uglifyjs docs, providing an example using the programmatic API as above, so as to avoid this issue for others in the future.