Módulo de comunidad impresionante

UglifyJS 3

UglifyJS es un conjunto de herramientas de analizador, minificador, compresor y embellecimiento 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 2.x UglifyJS se puede encontrar aquí .
  • uglify-js solo admite JavaScript (ECMAScript 5).
  • To minify ECMAScript 2015 or above , transpile con herramientas como Babel .

Instalar en pc

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 comandos

1
uglifyjs [input files] [options]

UglifyJS puede tomar varios archivos de entrada. Se recomienda que primero pase los archivos de entrada y luego las opciones. UglifyJS analizará los archivos de entrada en secuencia y aplicará las opciones 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 coincidirá correctamente.

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

Si desea pasar sus opciones antes que los archivos de entrada, separe los dos con un guión doble 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 va a STDOUT.

Opciones de mapa fuente CLI

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

Opciones adicionales:

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

  • --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 de origen. 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 , dejará la salida en foo.min.js y el mapa de origen en foo.min.js.map . El mapeo de origen 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 de origen y los archivos originales como js/file1.js y js/file2.js ).

Composed source map

Cuando comprime código JS generado por un compilador como CoffeeScript, la asignación al código JS no será demasiado útil. En su lugar, le gustaría volver a asignar el código original (es decir, CoffeeScript). UglifyJS tiene un opción para tomar un mapa de fuente de entrada. Asumiendo 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 utilizar esta función, pase --source-map "content='/path/to/input/source.map'" o --source-map "content=inline" si el mapa de origen está incluido en línea con las fuentes.

Opciones de compresión CLI

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

Las opciones tienen 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 manipulación CLI

Para habilitar el manipulador, debe pasar --mangle ( -m ). Se --mangle siguientes opciones (separadas por comas):

  • toplevel (por defecto false ): modifica los nombres declarados en el ámbito de nivel superior.

  • eval (por defecto false ): modifica los nombres visibles en los ámbitos donde se usan eval o with .

Cuando la alteración está habilitada, pero desea evitar que se --mangle reserved ciertos nombres, 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 modifiquen los nombres de require , exports y $ .

CLI manipulando nombres de propiedad ( --mangle-props )

Nota: ESTO PROBABLEMENTE ROMPERÁ SU CÓDIGO. La modificación de los nombres de las propiedades es un paso independiente, diferente de la --mangle-props los nombres de las variables. Pase --mangle-props para habilitarla. Manipulará todas las propiedades en el código de entrada con la excepción de las propiedades DOM integradas 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 las builtins JavaScript):

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._());

Mangle 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 debería cubrir la mayoría de las propiedades estándar de JS y DOM definidas en varios navegadores. Pase --mangle-props domprops para deshabilitar esta función.

Se puede usar una expresión regular para definir qué nombres de propiedad deben modificarse. Por ejemplo, --mangle-props regex=/^_/ solo modificará los nombres de propiedad que comiencen con un guión bajo.

Cuando comprime varios archivos usando esta opción, para que funcionen juntos al final, debemos asegurarnos de que de alguna manera 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. Inicialmente debería estar 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 consistentes entre sí en términos de nombres de propiedad alterados.

No es necesario usar el caché de nombres 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 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 se o.foo a o._$foo$_ con esta opción. Esto permite alterar las propiedades de una base de código grande sin dejar de ser capaz de depurar el código e identificar dónde está estropeando las 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 compile un script para identificar cómo se destrozó una propiedad Una técnica consiste en pasar un número aleatorio en cada compilación para simular el cambio de manipulación con diferentes entradas (por ejemplo, cuando actualiza el script de entrada con nuevas propiedades) y para ayudar a identificar errores como escribir claves mutiladas en el almacenamiento.

Referencia de API

Suponiendo 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 única función de alto nivel, minify(code, options) , que realizará todas las fases de minificación de una 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 archivo 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 la caché de nombres 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: que a diferencia de ʻuglify-js@2.x , the la API 3.x` hace los errores de lanzamiento, no para lograr un efecto similar. Lo siguiente podría hacer:

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

Minificar opciones

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

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

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

  • mangle (valor predeterminado true ): pase false para omitir los nombres de alteración o pase un objeto para especificar las opciones de alteración (ver más abajo).

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

  • sourceMap (por defecto false ): pase un objeto si desea especificar las opciones del mapa de origen .

  • toplevel (por defecto false ) toplevel en true si desea habilitar el cambio de nombre de función y variable de nivel superior y eliminar variables y funciones no utilizadas.

  • nameCache (valor predeterminado null ): nameCache un objeto vacío {} o un objeto nameCache usado anteriormente si desea almacenar en caché nombres de variable y propiedad nameCache en múltiples invocaciones de minify() . Nota: esta es una propiedad de lectura / escritura. minify() leer el estado de la caché de nombres de este objeto y actualizarlo durante la minificación para que el usuario pueda reutilizarlo o conservarlo externamente.

  • ie8 (predeterminado false ): establecido en 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 .

Minimizar la estructura de opciones

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 de origen 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 usa para establecer file atributo de file (consulte la especificación ) en el archivo de mapa de origen.

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

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

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 para ello, 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 lugar, puede omitir sourceMap.url .

Opciones de análisis

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

  • html5_comments (predeterminado true )

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

Comprimir opciones

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

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

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

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

  • conditionals (predeterminado: true ): aplica optimizaciones para if -s y expresiones condicionales

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

  • drop_console (predeterminado: false ) - Pase true para descartar llamadas a las funciones de la console.* Si desea eliminar 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, use pure_funcs en lugar.

  • drop_debugger (predeterminado: true ): elimina el debugger; declaraciones

  • evaluate (predeterminado: true ): intenta evaluar expresiones constantes

  • expression (predeterminado: false ): pase true para conservar 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 ) - declaraciones de función de elevación

  • hoist_props (predeterminado: true ): hoist_props propiedades 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); is convertido a f(1, 2); Nota: hoist_props funciona mejor con mangle habilitada, la compress opción passes ajustado a 2 o superior, y la compress opción toplevel habilitado.

  • hoist_vars (predeterminado: false ) - declaraciones de var elevación (esto es false por defecto porque parece aumentar el tamaño de la salida en general)

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

  • inline (predeterminado: true ): llamadas en línea para funcionar con una declaración simple / de return :

    • false - igual que 0
    • 0 - alineación deshabilitada
    • 1 - funciones simples en línea
    • 2 - funciones en línea con argumentos
    • 3 - funciones en línea con argumentos y variables
    • true - igual que 3
  • join_vars (predeterminado: true ): une declaraciones var consecutivas

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

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

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

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

  • negate_iife (predeterminado: true ): niega "Expresiones de función llamadas inmediatamente" donde se descarta el valor de retorno, para evitar los parens que insertaría el generador de código.

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

  • properties (por defecto: true ) - reescribe el acceso a la propiedad usando la notación de puntos, 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 verificará 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 eliminará, 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 se descartaría toda la declaración. La implementación actual agrega algo de sobrecarga (la compresión será más lenta). Asegúrese de que los símbolos debajo de pure_funcs también sean bajo mangle.reserved para evitar destrozar.

  • 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 efectos secundarios. Especifique "strict" para tratar foo.bar como libre de efectos secundarios solo cuando es seguro que foo no lanzará, es decir, no null o undefined .

  • reduce_funcs (predeterminado: true ): permite que las funciones de un solo uso se incluyan como expresiones de función cuando esté permitido, lo que permite una mayor optimización. Habilitado de forma predeterminada. La opción depende de que reduce_vars esté habilitado. 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 ): mejora la optimización en las variables asignadas y utilizadas como valores constantes.

  • sequences (predeterminado: true ): une declaraciones simples consecutivas usando el operador de coma. Puede establecerse 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 entonces el límite de sequences predeterminado es 200 Establezca la opción en false o 0 para deshabilitarla. La longitud de sequences más pequeña es 2 Un valor de sequences de 1 está protegido para ser equivalente a true y, como tal, significa 200 En raras ocasiones, el límite de secuencias predeterminado conduce a tiempos de compresión muy lentos en cuyo caso se recomienda un valor de 20 o menos.

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

  • switches (predeterminado: true ): elimina la duplicación y elimina las ramas de switch inalcanzables

  • toplevel (predeterminado: false ): elimina funciones no referenciadas ( "funcs" ) y / o variables ( "vars" ) en el alcance de nivel superior ( false de forma predeterminada, true para eliminar funciones y variables no referenciadas)

  • top_retain (predeterminado: null ): evita que las funciones y variables de nivel top_retain específicas se eliminen unused (puede ser una matriz, separada por comas, RegExp o función. Implica el nivel toplevel )

  • typeofs (predeterminado: true ): transforma 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 ): aplique transformaciones "inseguras" (discusión a continuación)

  • unsafe_comps (predeterminado: false ): comprime expresiones como a <= b asumiendo que ninguno de los operandos puede ser (obligado a) NaN .

  • unsafe_Function (predeterminado: false ): comprime y modifica la Function(args, code) cuando tanto los args como el code son literales de cadena.

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

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

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

  • unsafe_undefined (predeterminado: false ): sustituya void 0 si hay una variable denominada undefined en el alcance (el nombre de la variable se alterará, normalmente se reducirá a un solo carácter)

  • unused (predeterminado: true ): elimina funciones y variables sin referencia (las asignaciones de variables directas simples no cuentan como referencias a menos que se establezcan en "keep_assign" )

  • warnings (predeterminado: false ): muestra advertencias cuando se sueltan códigos inalcanzables o declaraciones no utilizadas, etc.

Opciones de Mangle

  • eval (por defecto false ): pasa true para modificar los nombres visibles en los ámbitos donde se usan eval o with .

  • keep_fnames (por defecto false ) - Pasa true para no alterar los nombres de las funciones. Útil para el código que se basa en Function.prototype.name . Vea también: la opción de compresión keep_fnames .

  • reserved (predeterminado [] ): pasa un conjunto de identificadores que deben excluirse de la manipulación. Ejemplo: ["foo", "bar"] .

  • toplevel (por defecto false ): pasa true para modificar los 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 (predeterminado: false ): use true para permitir la modificación de las propiedades del DOM integrado. No se recomienda anular esta configuración.

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

  • keep_quoted (predeterminado: false ) -— Solo modifica los nombres de propiedad sin comillas.

  • regex (predeterminado: null ): pasa un literal RegExp para modificar únicamente los nombres de propiedad que coinciden con la expresión regular.

  • reserved (predeterminado: [] ): no modifica los nombres de propiedad enumerados 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 (por defecto false ): escape de caracteres Unicode en cadenas y expresiones regulares (afecta a las directivas con caracteres no ascii que no son válidos)

  • beautify (valor predeterminado true ): si realmente se embellece 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 ): inserte siempre llaves if , for , do , while o with declaraciones, incluso si su cuerpo es una sola declaración.

  • comments (por defecto false ) - pase 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 (por defecto 4 )

  • indent_start (predeterminado 0 ): prefija todas las líneas con esa cantidad de espacios

  • inline_script (valor predeterminado true ): escapa de los comentarios HTML y la barra inclinada en las ocurrencias de </script> en cadenas

  • keep_quoted_props (por defecto false ): cuando está activado, evita que se eliminen las comillas de los nombres de propiedad en los objetos literales.

  • max_line_len (por defecto false ) - longitud máxima de línea (para código uglified)

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

  • preserve_line (valor predeterminado false ): pase true para conservar las líneas, pero solo funciona si beautify está configurado en false .

  • quote_keys (por defecto false ) - pasa true para citar todas las claves en objetos literales

  • quote_style (predeterminado 0 ): estilo de cita preferido para cadenas (también afecta a las directivas y los nombres de propiedad entre comillas):

    • 0 : prefiere comillas dobles, cambia a comillas simples cuando hay más comillas dobles en la propia cadena. 0 es mejor para el tamaño de gzip.
    • 1 - utilice siempre comillas simples
    • 2 - siempre use comillas dobles
    • 3 - usa siempre las citas originales
  • semicolons y semicolons (por defecto true ) - declaraciones separadas 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 lleva a una salida más legible de código desagradable (el tamaño antes de gzip podría ser más pequeño; el tamaño después de gzip insignificantemente mayor ).

  • shebang (por defecto true ) - preservar shebang #! en el 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 tratará de 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 (por defecto false ) - pasa true para envolver expresiones de función inmediatamente invocadas. Ver # 640 para más detalles.

Diverso

PUEDE pasar por usted --comments . El retener Cierto a los comentarios El resultado Por defecto en estilo de TI Mantendrá JSDoc que contenga comentarios "@preserve", "@license" o "@cc_on" (Compilación condicional para IE) Pasar por usted 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() ).