Impresionante módulo de comunidad

UglifyJS 3

UglifyJS es un kit de herramientas de analizador, minificador, compresor y embellecedor de JavaScript.

Nota:

  • uglify-js@3 tiene una API y una CLI simplificadas que no son compatibles con uglify-js@2 .
  • La documentación para las versiones de UglifyJS 2.x se puede encontrar aquí .
  • uglify-js solo es compatible con JavaScript (ECMAScript 5).
  • To minify ECMAScript 2015 or above , transpile utilizando herramientas como Babel .

Instalar

Primero asegúrese de haber instalado la última versión de node.js (es posible que deba reiniciar su computadora después de este paso).

Desde NPM para usar como una aplicación de línea de comandos:

1
npm install uglify-js -g

De NPM para uso programático:

1
npm install uglify-js

Uso de la línea de comando

1
uglifyjs [input files] [options]

UglifyJS puede tomar múltiples archivos de entrada. Se recomienda que primero pase los archivos de entrada, luego pase las opciones. UglifyJS analizará los archivos de entrada en secuencia y aplicará cualquier opción de compresión. Los archivos se analizan en el mismo ámbito global, es decir, una referencia de un archivo a alguna variable / función declarada en otro archivo se combinará correctamente.

Si no se especifica ningún archivo de entrada, UglifyJS leerá desde STDIN.

Si desea pasar sus opciones antes de los archivos de entrada, sepárelos con un doble guión para evitar que los archivos de entrada se utilicen como argumentos de opción:

1
uglifyjs --compress --mangle -- input.js

Command line options

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
-h, --help Print usage information. `--help options` for details on available options. -V, --version Print version number. -p, --parse <options> Specify parser options: `acorn` Use Acorn for parsing. `bare_returns` Allow return outside of functions. Useful when minifying CommonJS modules and Userscripts that may be anonymous function wrapped (IIFE) by the .user.js engine `caller`. `expression` Parse a single expression, rather than a program (for parsing JSON). `spidermonkey` Assume input files are SpiderMonkey AST format (as JSON). -c, --compress [options] Enable compressor/specify compressor options: `pure_funcs` List of functions that can be safely removed when their return values are not used. -m, --mangle [options] Mangle names/specify mangler options: `reserved` List of names that should not be mangled. --mangle-props [options] Mangle properties/specify mangler options: `builtins` Mangle property names that overlaps with standard JavaScript globals. `debug` Add debug prefix and suffix. `domprops` Mangle property names that overlaps with DOM properties. `keep_quoted` Only mangle unquoted properties. `regex` Only mangle matched property names. `reserved` List of names that should not be mangled. -b, --beautify [options] Beautify output/specify output options: `beautify` Enabled with `--beautify` by default. `preamble` Preamble to prepend to the output. You can use this to insert a comment, for example for licensing information. This will not be parsed, but the source map will adjust for its presence. `quote_style` Quote style: 0 - auto 1 - single 2 - double 3 - original `wrap_iife` Wrap IIFEs in parenthesis. Note: you may want to disable `negate_iife` under compressor options. -o, --output <file> Output file path (default STDOUT). Specify `ast` or `spidermonkey` to write UglifyJS or SpiderMonkey AST as JSON to STDOUT respectively. --comments [filter] Preserve copyright comments in the output. By default this works like Google Closure, keeping JSDoc-style comments that contain "@license" or "@preserve". You can optionally pass one of the following arguments to this flag: - "all" to keep all comments - a valid JS RegExp like `/foo/` or `/^!/` to keep only matching comments. Note that currently not *all* comments can be kept when compression is on, because of dead code removal or cascading statements into sequences. --config-file <file> Read `minify()` options from JSON file. -d, --define <expr>[=value] Global definitions. --ie8 Support non-standard Internet Explorer 8. Equivalent to setting `ie8: true` in `minify()` for `compress`, `mangle` and `output` options. By default UglifyJS will not try to be IE-proof. --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name. --name-cache <file> File to hold mangled name mappings. --self Build UglifyJS as a library (implies --wrap UglifyJS) --source-map [options] Enable source map/specify source map options: `base` Path to compute relative paths from input files. `content` Input source map, useful if you're compressing JS that was generated from some other original code. Specify "inline" if the source map is included within the sources. `filename` Name and/or location of the output source. `includeSources` Pass this flag if you want to include the content of source files in the source map as sourcesContent property. `root` Path to the original source to be included in the source map. `url` If specified, path to the source map to append in `//# sourceMappingURL`. --timings Display operations run time on STDERR. --toplevel Compress and/or mangle variables in top level scope. --verbose Print diagnostic messages. --warn Print warning messages. --wrap <name> Embed everything in a big function, making the “exports” and “global” variables available. You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.

Especifique --output ( -o ) para declarar el archivo de salida. De lo contrario, la salida irá a STDOUT.

Opciones de mapa fuente de CLI

UglifyJS puede generar un archivo de mapa fuente, que es muy útil para depurar su JavaScript comprimido. Para obtener un mapa fuente, pase --source-map --output output.js (el mapa fuente se escribirá en output.js.map ) .

Opciones adicionales:

  • --source-map "filename='<NAME>'" para especificar el nombre del mapa fuente.

  • --source-map "root='<URL>'" para pasar la URL donde se pueden encontrar los archivos originales.

  • --source-map "url='<URL>'" para especificar la URL donde se puede encontrar el mapa fuente. De lo contrario, UglifyJS asume que se está utilizando HTTP X-SourceMap y omitirá la directiva //# sourceMappingURL= .

Por ejemplo:

1 2 3
uglifyjs js/file1.js js/file2.js \ -o foo.min.js -c -m \ --source-map "root='http://foo.com/src',url='foo.min.js.map'"

Lo anterior comprimirá y file1.js y file2.js , file2.js la salida en foo.min.js y el mapa fuente en foo.min.js.map . El mapa fuente se referirá a http://foo.com/src/js/file1.js y http://foo.com/src/js/file2.js (de hecho, incluirá http://foo.com/src como la raíz del mapa fuente y los archivos originales como js/file1.js y js/file2.js ).

Composed source map

Cuando está comprimiendo el código JS que fue generado por un compilador como CoffeeScript, la asignación al código JS no será demasiado útil. En cambio, le gustaría volver al mapa original (es decir, CoffeeScript). UglifyJS tiene un opción para tomar un mapa fuente de entrada Suponiendo que tiene un mapeo de CoffeeScript → JS compilado, UglifyJS puede generar un mapa de CoffeeScript → JS comprimido mapeando cada token en el JS compilado a su ubicación original.

Para usar esta función, pase --source-map "content='/path/to/input/source.map'" o --source-map "content=inline" si el mapa fuente se incluye en línea con las fuentes.

Opciones de compresión CLI

--compress pasar --compress ( -c ) para habilitar el compresor. Opcionalmente, puede pasar una lista de opciones de compresión separadas por comas.

Las opciones están en la forma foo=bar , o simplemente foo (esta última implica una opción booleana que desea establecer como true ; es efectivamente un atajo para foo=true ).

Ejemplo:

1
uglifyjs file.js -c toplevel,sequences=false

Opciones de cambio de CLI

Para habilitar el administrador necesita pasar --mangle ( -m ). Se --mangle siguientes opciones (separadas por comas):

  • toplevel (por defecto false ) -mangle nombres declarados en el ámbito de nivel superior.

  • eval (por defecto false ) - mangle nombres visibles en el DONDE Scopes eval o with se utilizan.

Cuando se habilita la anulación pero desea evitar que ciertos nombres se anulen, puede declarar esos nombres con --mangle reserved - pasar una lista de nombres separados por comas. Por ejemplo:

1
uglifyjs ... -m reserved=['$','require','exports']

para evitar que se require cambios, exports y $ nombres.

Nombres de propiedades de --mangle-props CLI ( --mangle-props )

Nota: ESTO PROBABLEMENTE ROMPIRÁ SU CÓDIGO. La manipulación de nombres de propiedades es un paso separado, diferente de la --mangle-props nombres de variables. Pase --mangle-props para habilitarlo. Destrozará todas las propiedades en el código de entrada con la excepción de las propiedades DOM incorporadas y propiedades en las clases principales de JavaScript. Por ejemplo:

1 2 3 4 5 6 7 8 9 10 11
// example.js var x = { baz_: 0, foo_: 1, calc: function() { return this.foo_ + this.baz_; } }; x.bar_ = 2; x["baz_"] = 3; console.log(x.calc());

Mangle todas las propiedades (excepto JavaScript builtins ):

1
$ uglifyjs example.js -c -m --mangle-props
1
var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());

Mangle todas las propiedades excepto las propiedades reserved :

1
$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
1
var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());

Descomprima todas las propiedades que coincidan con una regex :

1
$ uglifyjs example.js -c -m --mangle-props regex=/_$/
1
var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());

Combinando opciones de propiedades de mangle:

1
$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
1
var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());

Para que esto sea de alguna utilidad, evitamos alterar los nombres estándar de JS por defecto ( --mangle-props builtins para anular).

Se proporciona un archivo de exclusión predeterminado en tools/domprops.json que debe cubrir la mayoría de las propiedades estándar de JS y DOM definidas en varios navegadores. Pase --mangle-props domprops para deshabilitar esta característica.

Se puede usar una expresión regular para definir qué nombres de propiedad se deben --mangle-props regex=/^_/ , por ejemplo, --mangle-props regex=/^_/ solo alterará los nombres de propiedades que comienzan con un guión bajo.

Cuando comprime varios archivos con esta opción, para que funcionen juntos al final, debemos asegurarnos de alguna manera de que una propiedad se destruya con el mismo nombre en todos ellos. Para esto, pase --name-cache filename.json y UglifyJS mantendrá estas asignaciones en un archivo que luego se puede reutilizar. Debería estar inicialmente vacío. Ejemplo:

1 2 3
$ rm -f /tmp/cache.json # start fresh $ uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js $ uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js

Ahora, part1.js y part2.js serán coherentes entre sí en términos de nombres de propiedad destrozados.

No es necesario usar el nombre de caché si comprime todos sus archivos en una sola llamada a UglifyJS.

--mangle-props keep_quoted nombres sin comillas ( --mangle-props keep_quoted )

El uso del nombre de la propiedad entre comillas ( o["foo"] ) reserva el nombre de la propiedad ( foo ) para que no se altere en todo el script, incluso cuando se utiliza en un estilo sin comillas ( o.foo ). Ejemplo:

1 2 3 4 5 6 7
// stuff.js var o = { "foo": 1, bar: 3 }; o.foo += o.bar; console.log(o.foo);
1
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m
1
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);

Debugging property name mangling

También puede pasar --mangle-props debug para alterar los nombres de las propiedades sin oscurecerlos por completo. Por ejemplo, la propiedad o.foo cambiaría a o._$foo$_ con esta opción. Esto permite la manipulación de propiedades de una base de código grande sin dejar de ser capaz de depurar el código e identificar dónde destrozar está rompiendo cosas.

1
$ uglifyjs stuff.js --mangle-props debug -c -m
1
var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);

También puede pasar un sufijo personalizado usando --mangle-props debug=XYZ . Esto luego o.foo a o._$foo$XYZ_ . Puede cambiar esto cada vez que compila un script para identificar cómo una propiedad se destrozó Una técnica consiste en pasar un número aleatorio en cada compilación para simular cambios de manipulación con diferentes entradas (por ejemplo, a medida que actualiza el script de entrada con nuevas propiedades) y para ayudar a identificar errores como escribir claves maltratadas en el almacenamiento.

Referencia de API

Asumiendo la instalación a través de NPM, puede cargar UglifyJS en su aplicación de esta manera:

1
var UglifyJS = require("uglify-js");

Hay una sola función de alto nivel, minify(code, options) , que realizará todas las fases de minificación de manera configurable. Por defecto, minify() habilitará las opciones compress y mangle . Ejemplo:

1 2 3 4
var code = "function add(first, second) { return first + second; }"; var result = UglifyJS.minify(code); console.log(result.error); // runtime error, or `undefined` if no error console.log(result.code); // minified output: function add(n,d){return n+d}

Puede minify más de un archivo JavaScript a la vez utilizando un objeto para el primer argumento donde las claves son nombres de archivos y los valores son código fuente:

1 2 3 4 5 6 7
var code = { "file1.js": "function add(first, second) { return first + second; }", "file2.js": "console.log(add(1 + 2, 3 + 4));" }; var result = UglifyJS.minify(code); console.log(result.code); // function add(d,n){return d+n}console.log(add(3,7));

La opción de nivel toplevel :

1 2 3 4 5 6 7 8
var code = { "file1.js": "function add(first, second) { return first + second; }", "file2.js": "console.log(add(1 + 2, 3 + 4));" }; var options = { toplevel: true }; var result = UglifyJS.minify(code, options); console.log(result.code); // console.log(3+7);

La opción nameCache :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
var options = { mangle: { toplevel: true, }, nameCache: {} }; var result1 = UglifyJS.minify({ "file1.js": "function add(first, second) { return first + second; }" }, options); var result2 = UglifyJS.minify({ "file2.js": "console.log(add(1 + 2, 3 + 4));" }, options); console.log(result1.code); // function n(n,r){return n+r} console.log(result2.code); // console.log(n(3,7));

Puede conservar el nombre de caché en el sistema de archivos de la siguiente manera:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
var cacheFileName = "/tmp/cache.json"; var options = { mangle: { properties: true, }, nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8")) }; fs.writeFileSync("part1.js", UglifyJS.minify({ "file1.js": fs.readFileSync("file1.js", "utf8"), "file2.js": fs.readFileSync("file2.js", "utf8") }, options).code, "utf8"); fs.writeFileSync("part2.js", UglifyJS.minify({ "file3.js": fs.readFileSync("file3.js", "utf8"), "file4.js": fs.readFileSync("file4.js", "utf8") }, options).code, "utf8"); fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");

Un ejemplo de una combinación de opciones minify() :

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
var code = { "file1.js": "function add(first, second) { return first + second; }", "file2.js": "console.log(add(1 + 2, 3 + 4));" }; var options = { toplevel: true, compress: { global_defs: { "@console.log": "alert" }, passes: 2 }, output: { beautify: false, preamble: "/* uglified */" } }; var result = UglifyJS.minify(code, options); console.log(result.code); // /* uglified */ // alert(10);"

Para producir advertencias:

1 2 3 4 5 6
var code = "function f(){ var u; return 2 + 3; }"; var options = { warnings: true }; var result = UglifyJS.minify(code, options); console.log(result.error); // runtime error, `undefined` in this case console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ] console.log(result.code); // function f(){return 5}

Un ejemplo de error:

1 2 3
var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"}); console.log(JSON.stringify(result.error)); // {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}

Nota: a diferencia de `uglify-js@2.x , the API 3.x` no arroja errores. Para lograr un efecto similar, se podría hacer lo siguiente:

1 2
var result = UglifyJS.minify(code, options); if (result.error) throw result.error;

Opciones de minificar

  • warnings (valor predeterminado false ): pase true para devolver las advertencias del compresor en result.warnings . Utilice el valor "verbose" para obtener advertencias más detalladas.

  • parse (predeterminado {} ): pasa un objeto si desea especificar algunas opciones de análisis adicionales .

  • compress (predeterminado {} ): pasa false para omitir la compresión por completo. Pasa un objeto para especificar opciones de compresión personalizadas.

  • mangle (valor predeterminado true ): pasar false para omitir nombres de cambio, o pasar un objeto para especificar opciones de cambio (ver más abajo).

    • mangle.properties (valor predeterminado false ): una subcategoría de la opción mangle. Pase un objeto para especificar opciones de propiedades de mangle personalizadas.
  • output ( null predeterminado): pase un objeto si desea especificar opciones de salida adicionales . Los valores predeterminados están optimizados para una mejor compresión.

  • sourceMap ( false predeterminado): pase un objeto si desea especificar las opciones del mapa fuente .

  • toplevel (valor predeterminado false ) toplevel a true si desea habilitar la variable de nivel superior y el cambio de nombre de función y descartar variables y funciones no utilizadas.

  • nameCache ( null predeterminado): nameCache un objeto vacío {} o un objeto nameCache utilizado nameCache si desea almacenar en caché los nombres de variables y propiedades en varias invocaciones de minify() . Nota: esta es una propiedad de lectura / escritura. minify() will lea el estado de la memoria caché de nombre de este objeto y actualícelo durante la minificación para que el usuario pueda reutilizarlo o conservarlo de forma externa.

  • ie8 (valor predeterminado false ) -conjunto a true para admitir IE8.

  • keep_fnames (predeterminado: false ) -pass true para evitar descartar o alterar los nombres de las funciones. Útil para el código que se basa en Function.prototype.name .

Estructura de opciones de minify

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
{ parse: { // parse options }, compress: { // compress options }, mangle: { // mangle options properties: { // mangle property options } }, output: { // output options }, sourceMap: { // source map options }, nameCache: null, // or specify a name cache object toplevel: false, ie8: false, warnings: false, }

Source map options

Para generar un mapa fuente:

1 2 3 4 5 6 7 8
var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, { sourceMap: { filename: "out.js", url: "out.js.map" } }); console.log(result.code); // minified output console.log(result.map); // source map

Tenga en cuenta que el mapa fuente no se guarda en un archivo, solo se devuelve en result.map . El valor pasado para sourceMap.url solo se usa para establecer //# sourceMappingURL=out.js.map en result.code . El valor de filename solo se utiliza para establecer file atributo de file (ver las especificaciones ) en el archivo de mapa fuente.

Puede configurar la opción sourceMap.url para que esté "inline" y el mapa fuente se agregará al código.

También puede especificar la propiedad sourceRoot para que se incluya en el mapa fuente:

1 2 3 4 5 6
var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, { sourceMap: { root: "http://example.com/src", url: "out.js.map" } });

Si está comprimiendo JavaScript compilado y tiene un mapa fuente, puede usar sourceMap.content :

1 2 3 4 5 6 7
var result = UglifyJS.minify({"compiled.js": "compiled code"}, { sourceMap: { content: "content from compiled.js.map", url: "minified.js.map" } }); // same as before, it returns `code` and `map`

Si está utilizando el encabezado X-SourceMap , puede omitir sourceMap.url .

Opciones de análisis

  • bare_returns (valor predeterminado false ): bare_returns declaraciones de return nivel superior

  • html5_comments (valor predeterminado true )

  • #!command shebang (predeterminado true ) -support #!command como primera línea

Opciones de compresión

  • arguments (predeterminado: true ): reemplaza los arguments[index] con el nombre del parámetro de función siempre que sea posible.

  • booleans (valor predeterminado: true ): booleans optimizaciones para el contexto booleano, por ejemplo !!a ? b : c → a ? b : c

  • collapse_vars (valor predeterminado: true ) -Contraer variables no constantes de un solo uso, si los efectos secundarios lo permiten.

  • comparisons (valor predeterminado: true ): aplique ciertas optimizaciones a los nodos binarios, por ejemplo !(a <= b) → a > b , intenta negar los nodos binarios, por ejemplo a = !b && !c && !d && !e → a=!(b||c||d||e) etc.

  • conditionals (predeterminado: true ) optimizaciones de aplicación para if -s y expresiones condicionales

  • dead_code (predeterminado: true ) dead_code código inalcanzable

  • drop_console (valor predeterminado: false ) -Pass true para descartar llamadas a la console.* funciones. Si desea descartar una llamada de función específica como console.info y / o retener los efectos secundarios de los argumentos de la función después de pure_funcs llamada a la función, utilice pure_funcs en su lugar

  • drop_debugger (predeterminado: true ) drop_debugger debugger; declaraciones

  • evaluate (predeterminado: true ) -intento para evaluar expresiones constantes

  • expression (predeterminado: false ) -Pass true para preservar los valores de finalización de las declaraciones de terminal sin return , por ejemplo, en marcadores.

  • global_defs (predeterminado: {} ) -ver compilación condicional

  • hoist_funs (predeterminado: false ) hoist_funs declaraciones de funciones

  • hoist_props (predeterminado: true ) hoist_props propiedades de hoist_props de objetos constantes y literales de matriz en variables regulares sujetas a un conjunto de restricciones.Por ejemplo: var o={p:1, q:2}; f(op, oq); es convertido a f(1, 2); Nota: hoist_props funciona mejor con la función de mangle habilitada, la opción de compress passes establecida a 2 o superior, y la opción de compress toplevel habilitado.

  • hoist_vars (predeterminado: false ) hoist_vars declaraciones de var (esto es false de forma predeterminada porque parece aumentar el tamaño de la salida en general)

  • if_return (predeterminado: true ) if_return para if / return y if / continue

  • inline (predeterminado: true ) -inline llama a funcionar con una declaración simple / return :

    • false mismo como 0
    • 0 desactivada
    • 1 funciones simples en línea
    • 2 funciones en línea con argumentos
    • 3 funciones en línea con argumentos y variables
    • true mismo que 3
  • join_vars (predeterminado: true ) join_vars declaraciones var consecutivas

  • keep_fargs (valor predeterminado: true ): evita que el compresor descarte los argumentos de función no utilizados. Lo necesita para el código que se basa en Function.length .

  • keep_fnames (valor predeterminado: false ) keep_fnames true para evitar que el compresor descarte los nombres de funciones. Útil para el código que se basa en Function.prototype.name . Consulte también: la opción de keep_fnames .

  • keep_infinity (predeterminado: false ): keep_infinity true para evitar que Infinity se comprima en 1/0 , lo que puede causar problemas de rendimiento en Chrome.

  • loops (predeterminado: true ): optimizaciones para do , while y for bucles cuando podemos determinar estáticamente la condición.

  • negate_iife (predeterminado: true ) negate_iife "Expresiones de funciones negate_iife inmediato" donde se descarta el valor de retorno, para evitar los elementos parentales que insertaría el generador de código.

  • passes (predeterminado: 1 ): el número máximo de veces que se ejecuta la compresión. En algunos casos, más de un pase conduce a un código comprimido adicional. Tenga en cuenta que más pases tomarán más tiempo.

  • properties (valor predeterminado: true ): escriba el acceso a la propiedad utilizando la notación de punto, por ejemplo foo["bar"] → foo.bar

  • pure_funcs (predeterminado: null ): puede pasar una matriz de nombres y UglifyJS asumirá que esas funciones no producen efectos secundarios. PELIGRO: no comprobará si el nombre se redefine en el alcance. Un caso de ejemplo aquí, por ejemplo var q = Math.floor(a/b) . Si la variable q no se usa en otro lugar, UglifyJS la soltará, pero seguirá manteniendo Math.floor(a/b) , sin saber lo que hace. Puede pasar pure_funcs: [ 'Math.floor' ] para hacerle saber que esta función no producirá ningún efecto secundario, en cuyo caso la declaración completa se descartaría. La implementación actual agrega algo de sobrecarga (la compresión será más lenta). Asegúrese de que los símbolos bajo pure_funcs también bajo mangle.reserved para evitar destrozos.

  • pure_getters (predeterminado: "strict" ) -Si pasa true para esto, UglifyJS asumirá que el acceso a la propiedad del objeto (por ejemplo, foo.bar o foo["bar"] ) no tiene ningún efecto secundario. Especifique "strict" para trate foo.bar como libre de efectos secundarios solo cuando es seguro que foo no lanzará, es decir, no será null o undefined .

  • reduce_funcs (predeterminado: true ) reduce_funcs las funciones de un solo uso se inserten como expresiones de función cuando sea permisible, lo que permite una mayor optimización. Habilitada de manera predeterminada. La opción depende de que se reduce_vars . Algunos códigos se ejecutan más rápido en el motor Chrome V8 si esta opción está deshabilitada No afecta negativamente a otros navegadores importantes.

  • reduce_vars (predeterminado: true ) reduce_vars optimización en variables asignadas y utilizadas como valores constantes.

  • sequences (predeterminado: true ): se unen a sentencias simples consecutivas utilizando el operador de coma. Se puede establecer en un entero positivo para especificar el número máximo de secuencias de coma consecutivas que se generarán. Si esta opción se establece en true , el límite de sequences predeterminado es 200 Establezca la opción en false o 0 para deshabilitarla. La longitud más pequeña de las sequences es 2 Un valor de sequences de 1 es equivalente a true y, como tal, significa 200 En raras ocasiones, el límite predeterminado de secuencias conduce a tiempos de compresión muy lentos. en cuyo caso se recomienda un valor de 20 o menos.

  • side_effects (predeterminado: true ) side_effects false para deshabilitar las funciones potencialmente side_effects marcadas como "puro". Una llamada de función se marca como "puro" si una anotación de comentario /*@__PURE__*/ o /*#__PURE__*/ inmediatamente precede a llamada. Por ejemplo: /*@__PURE__*/foo();

  • switches (predeterminado: true ) -de-duplicate y elimina ramas de switch inalcanzables

  • toplevel (predeterminado: false ) "funcs" funciones sin referencia ( "funcs" ) y / o variables ( "vars" ) en el ámbito de nivel superior ( false por defecto, true para descartar tanto las funciones como las variables sin referencia)

  • top_retain (predeterminado: null ): top_retain funciones y variables específicas de nivel top_retain de la eliminación unused (puede ser matriz, separados por comas, RegExp o función. Implica nivel toplevel )

  • typeofs (predeterminado: true ) typeofs typeof foo == "undefined" en foo === void 0 Nota: se recomienda establecer este valor en false para IE10 y versiones anteriores debido a problemas conocidos.

  • unsafe (predeterminado: false ) -aplicar transformaciones "inseguras" (discusión a continuación)

  • unsafe_comps (valor predeterminado: false ) unsafe_comps expresiones como a <= b suponiendo que ninguno de los operandos pueda ser (forzado a) NaN .

  • unsafe_Function (predeterminado: false ) unsafe_Function y mangle Function(args, code) cuando tanto args como code son literales de cadena.

  • unsafe_math (predeterminado: false ): unsafe_math expresiones numéricas como 2 * x * 3 en 6 * x , lo que puede dar resultados imprecisos de coma flotante.

  • unsafe_proto (predeterminado: false ): unsafe_proto expresiones como Array.prototype.slice.call(a) en [].slice.call(a)

  • unsafe_regexp (predeterminado: false ) unsafe_regexp sustituciones de variables con valores RegExp la misma manera que si fueran constantes.

  • unsafe_undefined (por defecto: false ) -sustituye void 0 si hay una variable llamada undefined en alcance (el nombre de la variable será mutilado, generalmente reducido a un solo carácter)

  • unused (por defecto: true ) - Funciones caen sin referencias y las variables (las simples asignaciones de variables directos no cuentan como el menos que el SET a las referencias "keep_assign" )

  • warnings (predeterminado: false ): muestra advertencias al soltar código inalcanzable o declaraciones no utilizadas, etc.

Opciones de mangle

  • eval (valor predeterminado false ) -Pass true para alterar nombres visibles en ámbitos donde se utilizan eval o with .

  • keep_fnames (valor predeterminado false ) keep_fnames true para no keep_fnames nombres de funciones. Útil para el código que se basa en Function.prototype.name . Consulte también: la opción de compresión keep_fnames .

  • reserved (predeterminado [] ) -Pasar una matriz de identificadores que deben excluirse de la manipulación. Ejemplo: ["foo", "bar"] .

  • toplevel (por defecto false ) -Pass true para destrozar nombres declarados en el ámbito de nivel superior.

Ejemplos:

1 2 3 4 5
// test.js var globalVar; function funcName(firstLongName, anotherLongName) { var myVariable = firstLongName + anotherLongName; }
1 2 3 4 5 6 7 8 9 10
var code = fs.readFileSync("test.js", "utf8"); UglifyJS.minify(code).code; // 'function funcName(a,n){}var globalVar;' UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code; // 'function funcName(firstLongName,a){}var globalVar;' UglifyJS.minify(code, { mangle: { toplevel: true } }).code; // 'function n(n,a){}var a;'

Mangle properties options

  • builtins (valor predeterminado: false ): se usa true para permitir la manipulación de propiedades DOM integradas. No se recomienda anular esta configuración.

  • debug (predeterminado: false ) -— Mangle los nombres con el nombre original todavía presente. Pase una cadena vacía "" para habilitarla, o una cadena no vacía para establecer el sufijo de depuración.

  • keep_quoted (valor predeterminado: false ) -— Solo destrozar nombres de propiedades sin comillas.

  • regex (valor predeterminado: null ): pase un literal RegExp para alterar solo los nombres de propiedades que coincidan con la expresión regular.

  • reserved (predeterminado: [] ) -No alterar los nombres de propiedades que figuran en la matriz reserved .

Opciones de salida

El generador de código intenta generar el código más corto posible de forma predeterminada. En caso de que desee una salida embellecida, pase --beautify ( -b ). Opcionalmente, puede pasar argumentos adicionales que controlen la salida del código:

  • ascii_only (predeterminado false ) ascii_only caracteres Unicode en cadenas y expresiones regulares (afecta a las directivas con caracteres no ascii que no son válidos)

  • beautify ( true defecto) -si realmente embellecer la salida. Pasar -b establecerá esto en verdadero, pero es posible que deba pasar -b incluso cuando desee generar código minificado, para especificar argumentos adicionales, para que pueda use -b beautify=false para anularlo.

  • braces (por defecto false ): siempre inserta llaves en if , for , do , while o with declaraciones, incluso si su cuerpo es una sola declaración.

  • comments (valor predeterminado false ) -pass true o "all" para preservar todos los comentarios, "some" para preservar algunos comentarios, una cadena de expresión regular (por ejemplo, /^!/ ) o una función.

  • indent_level (predeterminado 4 )

  • indent_start (predeterminado 0 ) -prefijar todas las líneas por tantos espacios

  • inline_script ( true predeterminado) inline_script comentarios HTML y la barra diagonal en las apariciones de </script> en cadenas

  • keep_quoted_props (valor predeterminado false ): keep_quoted_props activa, evita que se eliminen las comillas de los nombres de propiedad en literales de objeto.

  • max_line_len ( false predeterminado) max_line_len línea (para código uglified)

  • preamble ( null predeterminado): cuando se pasa, debe ser una cadena y se agregará literalmente a la salida literalmente. El mapa fuente se ajustará para este texto. Se puede utilizar para insertar un comentario que contenga información de licencia, por ejemplo.

  • preserve_line (por defecto false ) -pass true para preservar líneas, pero solo funciona si beautify se establece en false .

  • quote_keys (valor predeterminado false ) quote_keys true para citar todas las claves en objetos literales

  • estilo de cotización preferido para las cadenas de caracteres quote_style (valor predeterminado 0 ) (afecta también a los nombres de propiedad y directivas entrecomillados):

    • 0 -prefiere comillas dobles, cambia a comillas simples cuando hay más comillas dobles en la cadena en sí. 0 es mejor para el tamaño de gzip.
    • 1 -siempre use comillas simples
    • 2 -siempre use comillas dobles
    • 3 -siempre use las citas originales
  • semicolons y semicolons (predeterminado true ): separe las declaraciones con punto y coma. Si pasa false , siempre que sea posible usaremos una nueva línea en lugar de un punto y coma, lo que dará como resultado una salida más legible de código uglified (el tamaño antes de gzip podría ser menor; el tamaño después de gzip es insignificantemente más grande) )

  • shebang ( true predeterminado) -conserva shebang #! en preámbulo (scripts bash)

  • webkit (por defecto false ) habilita soluciones para los errores de WebKit. Los usuarios de PhantomJS deben establecer esta opción en true .

  • width (predeterminado 80 ): solo tiene efecto cuando el embellecimiento está activado, esto especifica un ancho de línea (orientativo) que el embellecedor intentará obedecer. Se refiere al ancho del texto de la línea (excluyendo la sangría). No funciona muy bien actualmente, pero hace que el código generado por UglifyJS sea más legible.

  • wrap_iife (valor predeterminado false ) wrap_iife true para ajustar las expresiones de función invocadas de inmediato. Consulte # 640 para obtener más detalles.

Misceláneo

Usted puede pasar por --comments La conservar algunos de Comentarios La salida de forma predeterminada en TI-estilo le mantendrá jsdoc que contienen comentarios "@preserve", "@license" o "@cc_on" (compilación condicional para los IEs) Pasar por Puede.. --comments all to keep all the comments, or a valid JavaScript regexp to keep only comments that match this regexp. For example --comments /^!/ will keep comments like /*! Copyright Notice */ .

Note, however, that there might be situations where comments are lost. For example:

1 2 3 4 5 6 7
function f() { /** @preserve Foo Bar */ function g() { // this function is never called } return something(); }

Even though it has "@preserve", the comment will be lost because the inner function g (which is the AST node to which the comment is attached to) is discarded by the compressor as not referenced.

The safest comments where to place copyright information (or other info that needs to be kept in the output) are comments attached to toplevel nodes.

The unsafe compress option

It enables some transformations that might break code logic in certain contrived cases, but should be fine for most code. You might want to try it on your own code, it should reduce the minified size. Here's what happens when this flag is on:

  • new Array(1, 2, 3) or Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp) or exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...) → we discard the new

Conditional compilation

You can use the --define ( -d ) switch in order to declare global variables that UglifyJS will assume to be constants (unless defined in scope). For example if you pass --define DEBUG=false then, coupled with dead code removal UglifyJS will discard the following from the output:

1 2 3
if (DEBUG) { console.log("debug stuff"); }

You can specify nested constants in the form of --define env.DEBUG=false .

UglifyJS will warn about the condition being always false and about dropping unreachable code; for now there is no option to turn off only this specific warning, you can pass warnings=false to turn off all warnings.

Another way of doing that is to declare your globals as constants in a separate file and include it into the build. For example you can have a build/defines.js file with the following:

1 2 3
var DEBUG = false; var PRODUCTION = true; // etc.

and build your code like this:

1
uglifyjs build/defines.js js/foo.js js/bar.js... -c

UglifyJS will notice the constants and, since they cannot be altered, it will evaluate references to them to the value itself and drop unreachable code as usual. The build will contain the const declarations if you use them. If you are targeting < ES6 environments which does not support const , using var with reduce_vars (enabled by default) should suffice.

Conditional compilation API

You can also use conditional compilation via the programmatic API. With the difference that the property name is global_defs and is a compressor property:

1 2 3 4 5 6 7 8
var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), { compress: { dead_code: true, global_defs: { DEBUG: false } } });

To replace an identifier with an arbitrary non-constant expression it is necessary to prefix the global_defs key with "@" to instruct UglifyJS to parse the value as an expression:

1 2 3 4 5 6 7 8
UglifyJS.minify("alert('hello');", { compress: { global_defs: { "@alert": "console.log" } } }).code; // returns: 'console.log("hello");'

Otherwise it would be replaced as string literal:

1 2 3 4 5 6 7 8
UglifyJS.minify("alert('hello');", { compress: { global_defs: { "alert": "console.log" } } }).code; // returns: '"console.log"("hello");'

Using native Uglify AST with minify()

1 2 3 4 5 6 7 8 9 10 11 12 13
// example: parse only, produce native Uglify AST var result = UglifyJS.minify(code, { parse: {}, compress: false, mangle: false, output: { ast: true, code: false // optional - faster if false } }); // result.ast contains native Uglify AST
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// example: accept native Uglify AST input and then compress and mangle // to produce both code and native AST. var result = UglifyJS.minify(ast, { compress: {}, mangle: {}, output: { ast: true, code: true // optional - faster if false } }); // result.ast contains native Uglify AST // result.code contains the minified code in string form.

Working with Uglify AST

Transversal and transformation of the native AST can be performed through TreeWalker and TreeTransformer respectively.

ESTree / SpiderMonkey AST

UglifyJS has its own abstract syntax tree format; for practical reasons we can't easily change to using the SpiderMonkey AST internally. However, UglifyJS now has a converter which can import a SpiderMonkey AST.

For example Acorn is a super-fast parser that produces a SpiderMonkey AST. It has a small CLI utility that parses one file and dumps the AST in JSON on the standard output. To use UglifyJS to mangle and compress that:

1
acorn file.js | uglifyjs -p spidermonkey -m -c

The -p spidermonkey option tells UglifyJS that all input files are not JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we don't use our own parser in this case, but just transform that AST into our internal AST.

Use Acorn for parsing

More for fun, I added the -p acorn option which will use Acorn to do all the parsing. If you pass this option, UglifyJS will require("acorn") .

Acorn is really fast (eg 250ms instead of 380ms on some 650K code), but converting the SpiderMonkey tree that Acorn produces takes another 150ms so in total it's a bit more than just using UglifyJS's own parser.

Uglify Fast Minify Mode

It's not well known, but whitespace removal and symbol mangling accounts for 95% of the size reduction in minified code for most JavaScript - not elaborate code transforms. One can simply disable compress to speed up Uglify builds by 3 to 4 times. In this fast mangle -only mode Uglify has comparable minify speeds and gzip sizes to butternut :

d3.js minify size gzip size minify time (seconds)
original 451,131 108,733 -
uglify-js@3.0.24 mangle=false, compress=false 316,600 85,245 0.70
uglify-js@3.0.24 mangle=true, compress=false 220,216 72,730 1.13
butternut@0.4.6 217,568 72,738 1.41
uglify-js@3.0.24 mangle=true, compress=true 212,511 71,560 3.36
babili@0.1.4 210,713 72,140 12.64

To enable fast minify mode from the CLI use:

1
uglifyjs file.js -m

To enable fast minify mode with the API use:

1
UglifyJS.minify(code, { compress: false, mangle: true });

Source maps and debugging

Various compress transforms that simplify, rearrange, inline and remove code are known to have an adverse effect on debugging with source maps. This is expected as code is optimized and mappings are often simply not possible as some code no longer exists. For highest fidelity in source map debugging disable the Uglify compress option and just use mangle .

Compiler assumptions

To allow for better optimizations, the compiler makes various assumptions:

  • .toString() and .valueOf() don't have side effects, and for built-in objects they have not been overridden.
  • undefined , NaN and Infinity have not been externally redefined.
  • arguments.callee , arguments.caller and Function.prototype.caller are not used.
  • The code doesn't expect the contents of Function.prototype.toString() or Error.prototype.stack to be anything in particular.
  • Getting and setting properties on a plain object does not cause other side effects (using .watch() or Proxy ).
  • Object properties can be added , removed and modified (not prevented with Object.defineProperty() , Object.defineProperties() , Object.freeze() , Object.preventExtensions() or Object.seal() ).