Microbundle: add uglify `passes: 3` compress option for smaller bundle sizes

Created on 28 Jan 2018  路  11Comments  路  Source: developit/microbundle

Recommend adding uglify passes: 3 compress option to:

https://github.com/developit/microbundle/blob/dcf99c620a6f9dbdad6e0e9089948dbeb2d5f82a/src/index.js#L264-L267

for smaller bundle sizes.

Example:

$ bin/uglifyjs -V
uglify-es 3.3.9
$ cat example.js 
var o = {
    foo: 1,
    bar: 2,
    square: x => x * x,
    cube: x => x * x * x,
};
console.log(o.foo, o.cube(3));



md5-e7904d4b05c9397448709dd46091f6d5



$ cat example.js | bin/uglifyjs --toplevel -mc
var o=1,l=o=>o*o*o;console.log(o,l(3));



md5-e7904d4b05c9397448709dd46091f6d5



$ cat example.js | bin/uglifyjs --toplevel -mc passes=2
console.log(1,(o=>o*o*o)(3));



md5-e7904d4b05c9397448709dd46091f6d5



$ cat example.js | bin/uglifyjs --toplevel -mc passes=3
console.log(1,27);
good first issue

Most helpful comment

we support mangle properties via package.json:

Could support either an .uglifyrc file or support all options in package.json:

{
    // ...
    "uglify": {
        parse: {
            // parse options
        },
        compress: {
            // compress options
        },
        mangle: {
            // mangle options

            properties: {
                // mangle property options
            }
        },
        output: {
            // output options
        },
        sourceMap: {
            // source map options
        },
        ecma: 5, // specify one of: 5, 6, 7 or 8
        keep_classnames: false,
        keep_fnames: false,
        ie8: false,
        nameCache: null, // or specify a name cache object
        safari10: false,
        toplevel: false,
        warnings: false,
    }
    // etc
}

Although the nameCache option can't work in a JSONish config - a read/write object is required.

All 11 comments

Against. Probably through option. It will lead to not intended effects, what about if you want that o object and o.cube function? ;d

There's no issue. It does the right thing.

$ cat ex2.js 
var o = {
    foo: 1,
    bar: 2,
    square: x => x * x,
    cube: x => x * x * x,
};
console.log(o.foo, o.cube(3), o);

$ cat ex2.js | bin/uglifyjs --toplevel -mc passes=3
var o={foo:1,bar:2,square:o=>o*o,cube:o=>o*o*o};console.log(o.foo,o.cube(3),o);
$ cat ex3.js 
var o = {
    foo: 1,
    bar: 2,
    square: x => x * x,
    cube: x => x * x * x,
};
console.log(o.cube(2), o.cube(3));

$ cat ex3.js | bin/uglifyjs --toplevel -mc passes=3
var o=o=>o*o*o;console.log(o(2),o(3));

Just to be clear, these optimizations are happening anyway. passes is just a more efficient way of running the uglify compressor repeatedly on the output:

$ cat example.js | bin/uglifyjs --toplevel -mc
var o=1,l=o=>o*o*o;console.log(o,l(3));

$ cat example.js | bin/uglifyjs --toplevel -mc | bin/uglifyjs --toplevel -mc
console.log(1,(o=>o*o*o)(3));

$ cat example.js | bin/uglifyjs --toplevel -mc | bin/uglifyjs --toplevel -mc | bin/uglifyjs --toplevel -mc
console.log(1,27);

I'm okay with increasing passes. I did some testing locally and it had no effect, but I know it depends on the nature of the code being compressed.

Is it possible to change uglify options from the CLI or other means?

Aside: the compress option unsafe: true is actually safe for code that does not alter JS built-in functions and classes.

$ echo 'console.log("foobar".substr(1,4));' | bin/uglifyjs -c
console.log("foobar".substr(1,4));

$ echo 'console.log("foobar".substr(1,4));' | bin/uglifyjs -c unsafe
console.log("ooba");

unsafe is also probably fine as a default - most modern libraries avoid modifying builtins anyway.

Just bringing these options to your attention. Up to you whether to act on it.

Would be nice to allow users to manually override these options somehow.

Agreed - we already support a "mangle" property in the package.json, maybe it'd be better to expand that to a "compress" property with these options?

Actually it'd be better to support manual overriding any of the minify options, not just compress and mangle.

options.mangle.properties in particular comes to mind as being useful. It can reduce bundle size by 40%.

parcel-bundler allows for an optional uglify options file, as an example.

@kzc we support mangle properties via package.json:

{
  // ...
  "mangle": {
    "regex": "^(_)"
  },
  // ...
}

we support mangle properties via package.json:

Could support either an .uglifyrc file or support all options in package.json:

{
    // ...
    "uglify": {
        parse: {
            // parse options
        },
        compress: {
            // compress options
        },
        mangle: {
            // mangle options

            properties: {
                // mangle property options
            }
        },
        output: {
            // output options
        },
        sourceMap: {
            // source map options
        },
        ecma: 5, // specify one of: 5, 6, 7 or 8
        keep_classnames: false,
        keep_fnames: false,
        ie8: false,
        nameCache: null, // or specify a name cache object
        safari10: false,
        toplevel: false,
        warnings: false,
    }
    // etc
}

Although the nameCache option can't work in a JSONish config - a read/write object is required.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

scttcper picture scttcper  路  11Comments

prateekbh picture prateekbh  路  17Comments

wcastand picture wcastand  路  16Comments

skipjack picture skipjack  路  11Comments

Conaclos picture Conaclos  路  11Comments