Módulo de comunidad impresionante

UglifyJS 3

UglifyJS es un conjunto de herramientas de analizador, minificador, compresor y embellecimiento de JavaScript.

Nota:

  • uglify-js@3tiene una API y una CLI simplificadas que no son compatibles con versiones anterioresuglify-js@2 .
  • La documentación de las 2.xversiones de UglifyJS se puede encontrar aquí .
  • uglify-js solo es compatible con JavaScript (ECMAScript 5).
  • Para minimizar ECMAScript 2015 o superior, transpile usando 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 alcance 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 de origen 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 X-SourceMapse está utilizando HTTP y omitirá la //# sourceMappingURL=directiva.

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 destruirá file1.jsy file2.jscolocará la salida foo.min.jsy el mapa de origen foo.min.js.map. El mapa de origen se referirá a http://foo.com/src/js/file1.jsy http://foo.com/src/js/file2.js(de hecho, aparecerá http://foo.com/src como la raíz del mapa de origen y los archivos originales como js/file1.jsy js/file2.js).

Composed source map

Cuando está comprimiendo 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 una 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 característica pase --source-map "content='/path/to/input/source.map'" o --source-map "content=inline"si el mapa fuente está incluido en línea con las fuentes.

Opciones de compresión CLI

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

Las opciones están en la forma foo=bar, o simplemente foo(la última implica una opción booleana que desea establecer 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 admiten las siguientes opciones (separadas por comas):

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

  • eval(predeterminado false): modifica los nombres visibles en los ámbitos en los que se utilizan evalo with.

Cuando la alteración está habilitada pero desea evitar que se alteren 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 cambien los nombres require, exportsy $.

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 modificación del nombre de las variables. Páselo --mangle-propspara habilitarlo. Modificará todas las propiedades en el código de entrada con la excepción de las propiedades DOM integradas y las propiedades en el núcleo de JavaScript. clases. 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 reservedpropiedades:

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 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 de forma predeterminada ( --mangle-props builtinspara anular).

Se proporciona un archivo de exclusión predeterminado en el tools/domprops.jsonque debería cubrir la mayoría de las propiedades estándar de JS y DOM definidas en varios navegadores. Pase --mangle-props dompropspara deshabilitar esta función.

Se puede utilizar 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 utilizando esta opción, para que funcionen juntos al final, debemos asegurarnos de que una propiedad se destruya con el mismo nombre en todos ellos. Para esto, pass --name-cache filename.json y UglifyJS mantendrán estas asignaciones en un archivo que luego se puede reutilizar. Inicialmente debe 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.jsy part2.jsserán coherentes entre sí en términos de nombres de propiedades destrozados.

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

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

El uso de nombre de propiedad entre comillas ( o["foo"]) reserva el nombre de propiedad ( foo) para que no se altere en todo el script, incluso cuando se usa 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 debugpara alterar los nombres de las propiedades sin oscurecerlos por completo. Por ejemplo, la propiedad o.foo se alteraría o._$foo$_con esta opción. Esto permite alterar las propiedades de una base de código grande y, al mismo tiempo, poder depurar el código e identificar dónde está alterando 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 se alteraría o.fooa o._$foo$XYZ_. Puede cambiar esto cada vez que compile un script para identificar cómo se destruyó una propiedad. Una técnica es pasar un número aleatorio en cada compilación para simular el cambio de alteración con diferentes entradas (por ejemplo, cuando actualiza el script de entrada con nuevas propiedades) y para ayudar a identificar errores como escribir claves dañadas 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");

Existe una única función de alto nivel minify(code, options), que realizará todas las fases de minificación de forma 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 minifymá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 toplevelopcion:

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 nameCacheopcion:

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 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 minify()opciones:

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 3.x`, la API no arroja errores. Para lograr un efecto similar, uno podría hacer lo siguiente:

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

Minificar opciones

  • warnings(predeterminado false): pasar truepara devolver las advertencias del compresor 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(predeterminado {}): pase falsepara omitir la compresión por completo. Pase un objeto para especificar opciones de compresión personalizadas .

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

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

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

  • toplevel(predeterminado false) -configure en truesi desea habilitar la modificación de nombre de función y variable de nivel superior y eliminar las variables y funciones no utilizadas.

  • nameCache(predeterminado null): pase un objeto vacío {}o un nameCacheobjeto usado anteriormente si desea almacenar en caché los nombres de variable y propiedad alterados a través de 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 lo actualizará durante la minificación para que el usuario pueda reutilizarlo o conservarlo externamente.

  • ie8(predeterminado false) -configurado en truepara admitir IE8.

  • keep_fnames(predeterminado false:) -pass truepara 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, es sólo regresó en result.map. El valor pasó para sourceMap.urlsolamente se utiliza para establecer //# sourceMappingURL=out.js.mapen result.code. El valor de filenamesolamente se utiliza para establecer fileel atributo (ver la especificación ) en el archivo de mapa de origen.

Puede establecer que la opción sourceMap.urlsea "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 X-SourceMapencabezado en su lugar, puede omitir sourceMap.url.

Opciones de análisis

  • bare_returns(predeterminado false): admite returndeclaraciones de nivel superior

  • html5_comments(por defecto true)

  • shebang(predeterminado true): soporte #!commandcomo primera línea

Comprimir opciones

  • arguments(predeterminado :) true: reemplácelo 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:): contraiga las variables no constantes de un solo uso, si los efectos secundarios lo permiten.

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

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

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

  • drop_console(predeterminado :) false- Pase truepara descartar llamadas a console.*funciones. Si desea eliminar una llamada a una función específica como console.infoy / o retener efectos secundarios de los argumentos de la función después de eliminar la llamada a la función, utilice pure_funcsen su lugar.

  • drop_debugger(predeterminado :) true- eliminar debugger;declaraciones

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

  • expression(predeterminado :) false- Pase truepara conservar los valores de finalización de las declaraciones de terminal sin return, por ejemplo, en bookmarklets.

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

  • hoist_funs(predeterminado false:) - declaraciones de función de elevación

  • hoist_props(predeterminado true:): eleva 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(o.p, o.q);se convierte a f(1, 2);. Nota: hoist_props funciona mejor con manglehabilitado, la compressopción passesestablecida en 2o superior y la compressopción toplevelhabilitada.

  • hoist_vars(predeterminado false:) - vardeclaraciones de 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 returndeclaración / simple :

    • false - igual que 0
    • 0 - alineación para discapacitados
    • 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:) - unirse a vardeclaraciones consecutivas

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

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

  • keep_infinity(predeterminado :) false- Pase truepara evitar que Infinityse comprima 1/0, lo que puede causar problemas de rendimiento en Chrome.

  • loops(por defecto true:) - optimizaciones para do, whiley forbucles cuando podemos determinar la condición estática.

  • negate_iife(predeterminado true:) - niega las "Expresiones de funciones 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 una pasada conduce a un código más comprimido. Tenga en cuenta que más pasadas tomarán más tiempo.

  • properties(predeterminado true:) - reescribe el acceso a la propiedad usando la notación de puntos, por ejemplofoo["bar"] → foo.bar

  • pure_funcs(predeterminado :) null- Puede pasar una serie de nombres y UglifyJS asumirá que esas funciones no producen efectos secundarios. PELIGRO: no comprobará si el nombre está redefinido en el alcance. Un caso de ejemplo aquí, por ejemplo var q = Math.floor(a/b). Si la variable qno es usado en otro lugar, UglifyJS lo eliminará, pero aún lo mantendrá Math.floor(a/b), sin saber qué 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 agrega algo de sobrecarga (la compresión será más lenta). Asegúrese de que los símbolos debajo pure_funcs también estén debajo mangle.reservedpara evitar alteraciones.

  • pure_getters(predeterminado :) "strict"- Si pasa truepor esto, UglifyJS asumirá que el acceso a la propiedad del objeto (por ejemplo, foo.baro foo["bar"]) no tiene ningún efecto secundario. Especifique "strict"tratar foo.barcomo libre de efectos secundarios solo cuando fooesté seguro de no lanzar, es decir, no nullo undefined.

  • reduce_funcs(predeterminado true:): permite que las funciones de un solo uso se incluyan como expresiones de función cuando sea posible, lo que permite una mayor optimización. Habilitada de forma predeterminada. La opción depende de que reduce_vars esté habilitada. Algunos códigos se ejecutan más rápido en el motor Chrome V8 si esta opción está inhabilitada. No lo hace de forma negativa afectar a otros navegadores importantes.

  • reduce_vars(predeterminado true:): mejora la optimización de las variables asignadas y utilizadas como valores constantes.

  • sequences(predeterminado true:): une declaraciones simples consecutivas utilizando 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, el sequenceslímite predeterminado es 200. Establecer opción en falseo 0 para deshabilitar. La sequenceslongitud más pequeña es 2. Un sequencesvalor de 1 tiene derechos adquiridos para ser equivalente a truey como tal significa 200. En raras ocasiones, el límite de secuencias predeterminado conduce a tiempos de compresión muy lentos, en cuyo caso 20se recomienda un valor de o menos.

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

  • switches(predeterminado true:) - eliminar duplicados y eliminar switchramas inalcanzables

  • toplevel(predeterminado false:): elimina funciones ( "funcs") y / o variables ( "vars") no referenciadas en el ámbito de nivel superior ( falsede forma predeterminada, truepara eliminar las funciones y variables no referenciadas)

  • top_retain(predeterminado null:): evita que se eliminen determinadas funciones y variables de nivel unusedsuperior (puede ser una matriz, una coma separada, una expresión regular o una función. Implica toplevel)

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

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

  • unsafe_comps(predeterminado :) false- comprime expresiones como a <= basumiendo que ninguno de los operandos puede ser (forzado a) NaN.

  • unsafe_Function(predeterminado false:) - comprime y mangle Function(args, code) cuando ambos argsy codeson cadenas literales.

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

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

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

  • unsafe_undefined(predeterminado false:): sustitúyalo void 0si hay una variable nombrada undefineden el alcance (el nombre de la variable se alterará, por lo general se reducirá a un solo carácter)

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

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

Opciones de Mangle

  • eval(predeterminado false): pase truepara modificar los nombres visibles en los ámbitos en los que se utilizan evalo with.

  • keep_fnames(predeterminado false) - Pasar truepara no alterar los nombres de las funciones. Útil para el código que se basa Function.prototype.name. Consulte también: la keep_fnames opción de compresión .

  • reserved(predeterminado []) - Pase AN BE Should Array de identificadores de los que se excluye la manipulación Ejemplo : ["foo", "bar"]..

  • toplevel(predeterminado false): pasa truepara 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: se utiliza truepara permitir la modificación de las propiedades DOM integradas. 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:) -— Mangle sólo nombres de propiedad sin comillas.

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

  • reserved(predeterminado []:) - No altere los nombres de propiedad que aparecen en la reservedmatriz.

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): escape de caracteres Unicode en cadenas y expresiones regulares (afecta a las directivas con caracteres no ascii que no son válidos)

  • beautify(predeterminado true): si realmente se embellecerá la salida. Pasar -bestablecerá esto en verdadero, pero es posible que deba pasar -bincluso cuando desee generar código minificado, para especificar argumentos adicionales, de modo que pueda usarlo -b beautify=falsepara anularlo.

  • braces(por defecto false) - Siempre en insertar llaves if, for, do, whileo withdeclaraciones, el incluso su cuerpo es la declaración UN SOLO SI.

  • comments(predeterminado false): pasa trueo "all"para preservar todos los comentarios, "some"para preservar algunos comentarios, una cadena de expresión regular (p /^!/. ej. ) 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(predeterminado true): escape de los comentarios HTML y la barra inclinada en las ocurrencias de </script>en cadenas

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

  • max_line_len(predeterminado false) - longitud máxima de línea (para código desactualizado)

  • preamble(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 usar para insertar un comentario que contenga información de licencia, por ejemplo.

  • preserve_line(predeterminado false): pase truepara conservar las líneas, pero solo funciona si beautifyestá configurado en false.

  • quote_keys(predeterminado false): pase truepara citar todas las claves en objetos literales

  • quote_style(predeterminado 0): estilo de comillas 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 0cadena.Es mejor para el tamaño de gzip.
    • 1 - utilice siempre comillas simples
    • 2 - siempre use comillas dobles
    • 3 - utilice siempre las citas originales
  • semicolons(por defecto true) - declaraciones separadas con punto y coma. Si pasa, falseentonces siempre que sea posible usaremos una nueva línea en lugar de un punto y coma, lo que conducirá a una salida más legible de código uglified (el tamaño antes de gzip podría ser más pequeño; el tamaño después de gzip podría ser insignificantemente más grande).

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

  • webkit(predeterminado false): habilita soluciones alternativas 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). Actualmente no funciona muy bien , pero hace que el código generado por UglifyJS sea más legible.

  • wrap_iife(predeterminado false): pase truepara ajustar las expresiones de función invocadas inmediatamente. Consulte el n. ° 640 para obtener más detalles.

Diverso

Puede pasar --commentspara retener ciertos comentarios en la salida. De forma predeterminada, mantendrá los comentarios estilo JSDoc que contengan "@preserve", "@license" o "@cc_on" (compilación condicional para IE). Puede pasar --comments allpara mantener todos los comentarios, o una expresión regular de JavaScript válida para mantener solo los comentarios que coincidan con esta expresión regular. Por ejemplo --comments /^!/ , mantendrá los comentarios como /*! Copyright Notice */.

Sin embargo, tenga en cuenta que puede haber situaciones en las que se pierdan los comentarios. Por ejemplo:

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

Aunque tiene "@preserve", el comentario se perderá porque gel compresor descarta la función interna (que es el nodo AST al que se adjunta el comentario) como no referenciada.

Los comentarios más seguros donde colocar la información de derechos de autor (u otra información que debe mantenerse en la salida) son los comentarios adjuntos a los nodos de nivel superior.

La unsafe compressopcion

Permite algunas transformaciones que pueden romper la lógica del código en ciertos casos artificiales, pero debería funcionar bien para la mayoría del código. Es posible que desee probarlo en su propio código, debería reducir el tamaño reducido. Esto es lo que sucede cuando esta marca está activada:

  • new Array(1, 2, 3)o Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp)o exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...) → descartamos el new

Conditional compilation

Puede usar el modificador --define( -d) para declarar variables globales que UglifyJS asumirá que son constantes (a menos que estén definidas en el alcance). Por ejemplo, si pasa --define DEBUG=falseentonces, junto con la eliminación del código muerto, UglifyJS descartará lo siguiente de la salida:

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

Puede especificar constantes anidadas en forma de --define env.DEBUG=false.

UglifyJS advertirá sobre la condición siempre falsa y sobre la eliminación de código inalcanzable; por ahora no hay opción para desactivar solo esta advertencia específica, puede pasar warnings=falsepara desactivar todas las advertencias.

Otra forma de hacerlo es declarar sus globales como constantes en un archivo separado e incluirlo en la compilación. Por ejemplo, puede tener un build/defines.jsarchivo con lo siguiente:

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

y construye tu código así:

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

UglifyJS notará las constantes y, dado que no se pueden alterar, evaluará las referencias a ellas al valor en sí y eliminará el código inalcanzable como de costumbre. La compilación contendrá las constdeclaraciones si las usa. Si está apuntando a entornos <ES6 que no no es compatible const, usar varcon reduce_vars(habilitado de forma predeterminada) debería ser suficiente.

Conditional compilation API

También puede usar la compilación condicional a través de la API programática. Con la diferencia de que el nombre de la propiedad es global_defsy es una propiedad del compresor:

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 } } });

Para reemplazar un identificador con una expresión arbitraria no constante, es necesario prefijar la global_defsclave con "@"para indicarle a UglifyJS que analice el valor como una expresión:

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

De lo contrario, sería reemplazado como literal de cadena:

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

Usando Uglify AST nativo con 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

La transversal y la transformación del AST nativo se pueden realizar mediante TreeWalkery TreeTransformer respectivamente.

ESTree / SpiderMonkey AST

UglifyJS tiene su propio formato de árbol de sintaxis abstracto; por razones prácticas, no podemos cambiar fácilmente al uso interno del SpiderMonkey AST.Sin embargo, UglifyJS ahora tiene un convertidor que puede importar un SpiderMonkey AST.

Por ejemplo, Acorn es un analizador súper rápido que produce un SpiderMonkey AST. Tiene una pequeña utilidad CLI que analiza un archivo y vuelca el AST en JSON en la salida estándar. Para usar UglifyJS para manipular y comprimir eso:

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

La -p spidermonkeyopción le dice a UglifyJS que todos los archivos de entrada no son JavaScript, sino código JS descrito en SpiderMonkey AST en JSON. Por lo tanto, no usamos nuestro propio analizador en este caso, solo transformamos ese AST en nuestro AST interno.

Use Acorn for parsing

Más por diversión, agregué la -p acornopción que usará Acorn para hacer todo el análisis. Si pasa esta opción, UglifyJS lo hará require("acorn").

Acorn es realmente rápido (por ejemplo, 250ms en lugar de 380ms en un código de 650K), pero convertir el árbol SpiderMonkey que Acorn produce toma otros 150ms, por lo que en total es un poco más que usar el analizador de UglifyJS.

Uglify Fast Minify Mode

No es bien conocida, pero los espacios en blanco de eliminación y Symbol mangling representa el 95% de al La reducción de tamaño en el código minified MOST JavaScript -. Código no Elaborar las transformaciones simplemente se puede desactivar compresspara acelerar afear se basa en un 3 a 4 veces An en el este es el modo RÁPIDO. mangleUglify tiene velocidades de minificación y tamaños de gzip comparables a butternut:

d3.js minimizar el tamaño tamaño gzip minificar el tiempo (segundos)
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

Para habilitar el modo de minificación rápida desde la CLI, use:

1
uglifyjs file.js -m

Para habilitar el modo de minificación rápida con el uso de la API:

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

Mapas de origen y depuración

Se compresssabe que varias transformaciones que simplifican, reorganizan, incorporan y eliminan el código tienen un efecto adverso en la depuración con mapas fuente. Esto se espera ya que el código está optimizado y las asignaciones a menudo simplemente no son posibles debido a que parte del código ya no existe. Para una mayor fidelidad en la fuente La depuración de mapas deshabilita la compressopción Uglify y solo usa mangle.

Compiler assumptions

Para permitir mejores optimizaciones, el compilador hace varias suposiciones:

  • .toString()y .valueOf()no tienen efectos secundarios, y para los objetos integrados no se han anulado.
  • undefined, NaNY Infinityno se han redefinido externamente.
  • arguments.callee, arguments.callerY Function.prototype.callerno se utilizan.
  • El código no espera que el contenido de Function.prototype.toString()ni Error.prototype.stacksea ​​nada en particular.
  • Obtener y configurar propiedades en un objeto simple no causa otros efectos secundarios (usar .watch()o Proxy).
  • Pueden añadirse el objeto Properties, eliminado y Modificado (no impedido con Object.defineProperty(), Object.defineProperties(), Object.freeze(), Object.preventExtensions()o Object.seal()).