Impresionante módulo comunitario

UgifyJS 3

UglifyJS é un analizador, minificador, compresor e ferramentas de embelecemento de JavaScript.

Nota:

  • uglify-js@3ten unha API e unha CLI simplificadas que non son compatibles conuglify-js@2 .
  • A documentación para 2.xas versións de UgliifyJS pódese atopar aquí .
  • uglify-jssó admite JavaScript (ECMAScript 5).
  • Para minificar ECMAScript 2015 ou superior, transpile usando ferramentas como Babel .

Instalar

Primeiro asegúrate de ter instalada a última versión de node.js (é posible que teñas que reiniciar o teu ordenador despois deste paso).

Desde NPM para usar como aplicación de liña de comandos:

1
npm install uglify-js -g

Desde NPM para uso programático:

1
npm install uglify-js

Uso da liña de comandos

1
uglifyjs [input files] [options]

UglifyJS pode tomar varios ficheiros de entrada. Recoméndase que pases primeiro os ficheiros de entrada e despois pases as opcións. UglifyJS analizará os ficheiros de entrada en secuencia e aplicará calquera opción de compresión. Os ficheiros analízanse no mesmo ámbito global, é dicir, unha referencia dun ficheiro a algunha variable/función declarada noutro ficheiro coincidirá correctamente.

Se non se especifica ningún ficheiro de entrada, UgliifyJS lerá desde STDIN.

Se queres pasar as túas opcións antes que os ficheiros de entrada, separa os dous cun guión dobre para evitar que os ficheiros 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 o ficheiro de saída. Se non, a saída pasa a STDOUT.

Opcións do mapa fonte da CLI

UglifyJS pode xerar un ficheiro de mapa de orixe, que é moi útil para depurar o teu JavaScript comprimido. Para obter un mapa de orixe, pasa --source-map --output output.js(o mapa de orixe escribirase en output.js.map).

Opcións adicionais:

  • --source-map "filename='<NAME>'"para especificar o nome do mapa de orixe.

  • --source-map "root='<URL>'"para pasar o URL onde se poden atopar os ficheiros orixinais.

  • --source-map "url='<URL>'"para especificar o URL onde se pode atopar o mapa de orixe. En caso contrario, UglifyJS asume que X-SourceMapse está a usar HTTP e omitirá a //# sourceMappingURL=directiva.

Por exemplo:

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'"

O anterior comprimirá e destrozará file1.jse file2.js, soltará a saída foo.min.jse o mapa de orixe en foo.min.js.map. A asignación de orixe farase referencia a http://foo.com/src/js/file1.jse http://foo.com/src/js/file2.js(de feito listarase http://foo.com/src como raíz do mapa de orixe e os ficheiros orixinais como js/file1.jse js/file2.js).

Composed source map

Cando estás comprimindo código JS que saíu un compilador como CoffeeScript, a asignación ao código JS non será demasiado útil. Pola contra, queres volver a mapear o código orixinal (por exemplo, CoffeeScript). UglifyJS ten un opción para tomar un mapa de orixe de entrada. Asumindo que tes unha asignación de CoffeeScript → JS compilado, UglifyJS pode xerar un mapa desde CoffeeScript → JS comprimido asignando cada token do JS compilado á súa localización orixinal.

Para usar esta función pase --source-map "content='/path/to/input/source.map'" ou --source-map "content=inline"se o mapa de orixe está incluído en liña coas fontes.

Opcións de compresión da CLI

Debes pasar --compress( -c) para activar o compresor. Opcionalmente podes pasar unha lista de opcións de compresión separadas por comas .

As opcións están na forma foo=bar, ou só foo(esta última implica unha opción booleana que quere configurar true; é efectivamente un atallo para foo=true).

Exemplo:

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

Opcións de mangle CLI

Para activar o mangler, cómpre pasar --mangle( -m). Admítense as seguintes opcións (separadas por comas):

  • toplevel(predeterminado false) -- destroza os nomes declarados no ámbito de nivel superior.

  • eval(predeterminado false) -- destroza os nomes visibles nos ámbitos onde se usa evalou .with

Cando a manipulación está activada pero queres evitar que determinados nomes sexan destrozados, podes declarar eses nomes con --mangle reserved— pase unha lista de nomes separados por comas. Por exemplo:

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

para evitar que se cambien os nomes require, exportse .$

CLI que modifica os nomes de propiedade ( --mangle-props)

Nota: ESTE PROBABLEMENTE ROMPE O TEU CÓDIGO. A manipulación de nomes de propiedade é un paso separado, diferente da manipulación de nomes de variables. Pasa --mangle-propspara activala. Destrozará todas as propiedades do código de entrada, a excepción das propiedades DOM integradas e as propiedades do JavaScript principal. clases. Por exemplo:

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

Destruír todas as 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());

Destroza todas as propiedades excepto as 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._());

Destroza todas as 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());

Opcións de combinación 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 isto sexa útil, evitamos manipular os nomes JS estándar por defecto ( --mangle-props builtinspara anular).

Ofrécese un ficheiro de exclusión predeterminado no tools/domprops.jsonque debería cubrir a maioría das propiedades estándar de JS e DOM definidas en varios navegadores. Pase --mangle-props dompropspara desactivar esta función.

Pódese usar unha expresión regular para definir que nomes de propiedade deben ser alterados. Por exemplo, --mangle-props regex=/^_/só se modificarán os nomes de propiedade que comecen cun guión baixo.

Cando comprimes varios ficheiros usando esta opción, para que funcionen xuntos ao final, debemos asegurarnos de que unha propiedade sexa alterada co mesmo nome en todos eles. Para iso, pass --name-cache filename.json e UglifyJS manterá estas asignacións nun ficheiro que despois se pode reutilizar. Inicialmente debería estar baleiro. Exemplo:

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

Agora, part1.jse part2.jsserán consistentes entre si en termos de nomes de propiedade mutilados.

Non é necesario usar a caché de nomes se comprimes todos os teus ficheiros nunha única chamada a UglifyJS.

Destrozando nomes sen comiñas ( --mangle-props keep_quoted)

Usar o nome da propiedade entre comiñas ( o["foo"]) reserva o nome da propiedade ( foo) para que non se destrúe en todo o script aínda que se use nun estilo sen comiñas ( o.foo). Exemplo:

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

Tamén podes pasar --mangle-props debugpara alterar os nomes das propiedades sen ocultalos por completo. Por exemplo, a propiedade o.foo modificaríase o._$foo$_con esta opción. Isto permite destrozar as propiedades dunha base de código grande, aínda que podes depurar o código e identificar onde se rompen as cousas.

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

Tamén podes pasar un sufixo personalizado usando --mangle-props debug=XYZ. Entón isto cambiaría o.fooa o._$foo$XYZ_. Podes cambialo cada vez que compiles un script para identificar como se destrozou unha propiedade. Unha técnica é pasar un número aleatorio a cada compilación para simular o cambio de alteración con diferentes entradas (por exemplo, mentres actualiza o script de entrada con novas propiedades) e para axudar a identificar erros como escribir chaves destrozadas no almacenamento.

Referencia da API

Asumindo a instalación mediante NPM, pode cargar UglifyJS na súa aplicación deste xeito:

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

Hai unha única función de alto nivel, minify(code, options), que realizará todas as fases de minificación dun xeito configurable. Por defecto minify()activará as opcións compress e mangle. Exemplo:

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}

Podes minifymáis dun ficheiro JavaScript á vez usando un obxecto para o primeiro argumento onde as claves son nomes de ficheiros e os valores son código fonte:

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

A toplevelopción:

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

A nameCacheopción:

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

Pode conservar a caché de nomes no sistema de ficheiros do seguinte xeito:

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 exemplo dunha combinación de minify()opcións:

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

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 exemplo de erro:

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 diferenza de uglify-js@2.x, a 3.xAPI non xera erros. Para conseguir un efecto similar, pódese facer o seguinte:

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

Minimizar as opcións

  • warnings(predeterminado false) — pase truepara devolver avisos de compresor en result.warnings. Use o valor "verbose"para avisos máis detallados.

  • parse(predeterminado {}): pase un obxecto se quere especificar algunhas opcións de análise adicionais .

  • compress(predeterminado {}): pase falsepara omitir a compresión por completo. Pase un obxecto para especificar opcións de compresión personalizadas .

  • mangle(predeterminado true): pase falsepara omitir os nomes alterados ou pase un obxecto para especificar as opcións de destrozo (consulte a continuación).

    • mangle.properties(predeterminado false) — unha subcategoría da opción de mangle. Pase un obxecto para especificar opcións de propiedade de mangle personalizadas .
  • output(predeterminado null) — pasa un obxecto se queres especificar opcións de saída adicionais . Os valores predeterminados están optimizados para a mellor compresión.

  • sourceMap(predeterminado false): pase un obxecto se desexa especificar as opcións do mapa de orixe .

  • toplevel(predeterminado false) - establécese truecomo se desexa activar a manipulación de nomes de funcións e variables de nivel superior e eliminar as variables e funcións non utilizadas.

  • nameCache(predeterminado null) - pase un obxecto baleiro {}ou un nameCacheobxecto usado anteriormente se desexa almacenar na memoria caché os nomes de variables e propiedades alterados en varias invocacións de minify(). Nota: esta é unha propiedade de lectura/escritura. minify()lerá o estado da caché de nomes deste obxecto e actualizalo. durante a minificación para que o usuario poida reutilizalo ou persistir externamente.

  • ie8(predeterminado false): configurado para trueadmitir IE8.

  • keep_fnames(predeterminado: false) - pase truepara evitar que se descarten ou destrúan os nomes das funcións. Útil para o código que depende de Function.prototype.name.

Minimizar a estrutura de opcións

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 xerar un mapa de orixe:

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

Teña en conta que o mapa de orixe non se garda nun ficheiro, só se devolve en result.map. O valor pasado sourceMap.urlsó se usa para establecer //# sourceMappingURL=out.js.mapen result.code. O valor de filenamesó se usa para definir fileo atributo (consulte a especificación ) no ficheiro de mapa de orixe.

Podes configurar a opción sourceMap.urlpara ser "inline"e engadirase o mapa fonte ao código.

Tamén pode especificar a propiedade sourceRoot para incluír no mapa de orixe:

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

Se estás comprimindo JavaScript compilado e tes un mapa de orixe para el, podes 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`

Se estás usando a X-SourceMapcabeceira no seu lugar, podes simplemente omitir sourceMap.url.

Opcións de análise

  • bare_returns(predeterminado false) -- admite returndeclaracións de nivel superior

  • html5_comments(predeterminado true)

  • shebang(predeterminado true) -- soporte #!commandcomo primeira liña

Opcións de compresión

  • arguments(predeterminado: true) -- substituír arguments[index]polo nome do parámetro da función sempre que sexa posible.

  • booleans(predeterminado: true) -- varias optimizacións para o contexto booleano, por exemplo!!a ? b : c → a ? b : c

  • collapse_vars(predeterminado: true) -- Contraer variables non constantes dun só uso, se os efectos secundarios o permiten.

  • comparisons(predeterminado: true) -- aplique certas optimizacións a nós binarios, por exemplo !(a <= b) → a > b, intentos de negar nós binarios, por exemplo, a = !b && !c && !d && !e → a=!(b||c||d||e)etc.

  • conditionals(predeterminado: true) -- aplica optimizacións para if-s e expresións condicionais

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

  • drop_console(predeterminado: false) -- Pasa truepara descartar chamadas a console.*funcións. Se queres eliminar unha chamada de función específica, como console.infoe/ou conservar os efectos secundarios dos argumentos de función despois de soltar a chamada de función, úsao pure_funcsno seu lugar.

  • drop_debugger(predeterminado: true) -- elimina debugger;instrucións

  • evaluate(predeterminado: true) -- tenta avaliar expresións constantes

  • expression(predeterminado: false) -- Pase truepara preservar os valores de finalización das instrucións do terminal sen return, por exemplo, nos marcadores.

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

  • hoist_funs(predeterminado: false) -- declaracións da función de elevación

  • hoist_props(predeterminado: true) -- eleva as propiedades de literais de obxectos e matrices constantes a variables normais suxeitas a un conxunto de restricións. Por exemplo: var o={p:1, q:2}; f(o.p, o.q);convértese en f(1, 2);. Nota: hoist_props funciona mellor con mangleenabled, a compressopción passesdefinida 2ou superior e a compressopción toplevelactivada.

  • hoist_vars(predeterminado: false) -- vardeclaracións de elevación (isto é false por defecto porque parece aumentar o tamaño da saída en xeral)

  • if_return(predeterminado: true) -- optimizacións para if/return e if/continue

  • inline(predeterminado: true) -- chamadas en liña para funcionar con returninstrución simple/:

    • false--o mesmo que0
    • 0-- Inline desactivado
    • 1-- funcións sinxelas en liña
    • 2-- funcións en liña con argumentos
    • 3-- funcións en liña con argumentos e variables
    • true--o mesmo que3
  • join_vars(predeterminado: ) -- únete declaracións trueconsecutivasvar

  • keep_fargs(predeterminado: true) -- Evita que o compresor descarte argumentos de funcións non utilizados. Necesitas isto para o código que depende de Function.length.

  • keep_fnames(predeterminado: false) -- Pasa truepara evitar que o compresor descarte os nomes das funcións. Útil para que o código se basee en Function.prototype.name. Consulte tamén: a keep_fnames opción de mangle .

  • keep_infinity(predeterminado: false) -- Pase truepara evitar Infinityque se comprima en 1/0, o que pode causar problemas de rendemento en Chrome.

  • loops(predeterminado: true) -- optimizacións para do, whilee forbucles cando podemos determinar estáticamente a condición.

  • negate_iife(predeterminado: true) -- nega "Expresións de función chamadas inmediatamente" onde se descarta o valor de retorno, para evitar os parénteses que inseriría o xerador de código.

  • passes(predeterminado: 1) -- O número máximo de veces para executar comprimir. Nalgúns casos, máis dunha pasada leva a un código comprimido máis. Ten en conta que máis pasadas levarán máis tempo.

  • properties(predeterminado: true) -- reescribe o acceso á propiedade usando a notación de puntos, por exemplofoo["bar"] → foo.bar

  • pure_funcs(predeterminado: null) -- Podes pasar unha matriz de nomes e UglifyJS asumirá que esas funcións non producen efectos secundarios. PERIGO: non comprobará se o nome está redefinido no ámbito. Un exemplo de caso aquí, por exemplo. var q = Math.floor(a/b)Se a variable qé non se usa noutro lugar, UglifyJS abandonarao, pero aínda así manterá o Math.floor(a/b), sen saber o que fai. Podes pasar pure_funcs: [ 'Math.floor' ]para informarlle de que esta función non producirá ningún efecto secundario, nese caso descartarase a declaración completa. a implementación actual engade algo de sobrecarga (a compresión será máis lenta). Asegúrate de que os símbolos debaixo pure_funcs tamén estean baixos mangle.reservedpara evitar destrozos.

  • pure_getters(predeterminado: "strict") -- Se pasa truepor isto, UglifyJS asumirá que o acceso á propiedade do obxecto (por exemplo, foo.barou foo["bar"]) non ten ningún efecto secundario. Especifique "strict"para tratar foo.barcomo libre de efectos secundarios só cando fooestea seguro de non lanzar, é dicir, non nullou undefined.

  • reduce_funcs(predeterminado: true) -- Permite que as funcións dun só uso estean integradas como expresións de función cando se permite unha optimización adicional. Activada de forma predeterminada. A opción depende de que reduce_vars estea activada. Algún código execútase máis rápido no motor Chrome V8 se esta opción está desactivada. Non o fai. afectan negativamente a outros navegadores principais.

  • reduce_vars(predeterminado: true) -- Mellora a optimización das variables asignadas e utilizadas como valores constantes.

  • sequences(predeterminado: true) -- une instrucións simples consecutivas mediante o operador de coma. Pódese establecer como un enteiro positivo para especificar o número máximo de secuencias de coma consecutivas que se xerarán. Se esta opción se define como límite truepredeterminado sequencesé 200. Establecer opción para falseou 0 para desactivar. A sequenceslonxitude máis pequena é 2. Un sequencesvalor de 1 é equivalente a truee como tal significa 200. En raras ocasións, o límite de secuencias predeterminados conduce a tempos de compresión moi lentos, caso en que 20se recomenda un valor igual ou inferior.

  • side_effects(predeterminado: true) -- Pasar falsepara desactivar funcións que se poden eliminar marcadas como "puras". Unha chamada de función márcase como "pura" se unha anotación de comentario /*@__PURE__*/ou /*#__PURE__*/precede inmediatamente á chamada. Por exemplo:/*@__PURE__*/foo();

  • switches(predeterminado: true) -- desduplica e elimina switchramas inalcanzables

  • toplevel(predeterminado: false) -- elimina funcións sen referencia ( "funcs") e/ou variables ( "vars") no ámbito de nivel superior ( falsepor defecto, trueelimina funcións e variables sen referencia)

  • top_retain(predeterminado: null) -- evita que se eliminen funcións e variables específicas de nivel superior unused(pode ser matriz, separadas por comas, ExpExp ou función. Implica toplevel)

  • typeofs(predeterminado: true) -- Transfórmase typeof foo == "undefined"en foo === void 0. Nota: recoméndase establecer este valor falsepara IE10 e versións anteriores debido a problemas coñecidos.

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

  • unsafe_comps(predeterminado: false) -- comprime expresións como a <= basumir que ningún dos operandos pode ser (coaccionado a) NaN.

  • unsafe_Function(predeterminado: false) -- comprimir e destrozar Function(args, code) cando ambos argse codeson literais de cadea.

  • unsafe_math(predeterminado: false) -- optimiza expresións numéricas como 2 * x * 3into 6 * x, que pode dar resultados imprecisos en coma flotante.

  • unsafe_proto(predeterminado: false) -- optimiza expresións como Array.prototype.slice.call(a)into[].slice.call(a)

  • unsafe_regexp(predeterminado: false) -- permite substitucións de variables con RegExpvalores do mesmo xeito que se fosen constantes.

  • unsafe_undefined(predeterminado: false) -- substitúeo void 0se hai unha variable nomeada undefinedno ámbito (o nome da variable será alterado, normalmente reducido a un só carácter)

  • unused(predeterminado: true) -- elimina funcións e variables sen referencia (as asignacións de variables directas sinxelas non contan como referencias a menos que se establezan en "keep_assign")

  • warnings(predeterminado: false) -- mostra avisos ao soltar código inalcanzable ou declaracións non utilizadas, etc.

Mangle opcións

  • eval(predeterminado false) -- Pasa truea destrozar os nomes visibles nos ámbitos onde se usan evalou .with

  • keep_fnames(predeterminado false) -- Pase truepara non alterar os nomes das funcións. Útil para o código baseado en Function.prototype.name. Consulte tamén: a keep_fnames opción de comprimir .

  • reserved(predeterminado []) -- Pase unha matriz de identificadores que deberían excluírse da manipulación. Exemplo: ["foo", "bar"].

  • toplevel(predeterminado false) -- Pasa truea mangle os nomes declarados no ámbito de nivel superior.

Exemplos:

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) -- Utilízase truepara permitir a alteración das propiedades DOM integradas. Non se recomenda anular esta configuración.

  • debug(predeterminado: false) -- Destroza os nomes co nome orixinal aínda presente. Pasa unha cadea baleira ""para activala ou unha cadea non baleira para establecer o sufixo de depuración.

  • keep_quoted(predeterminado: false) -- Destroza só os nomes de propiedade sen comiñas.

  • regex(predeterminado: null) -- Pase un literal de RegExp para modificar só os nomes de propiedade que coincidan coa expresión regular.

  • reserved(predeterminado: []) -- Non manipular os nomes das propiedades listados na reservedmatriz.

Opcións de saída

O xerador de código tenta producir o código máis curto posible de forma predeterminada. No caso de querer unha saída embelecida, pase --beautify( -b). Opcionalmente, pode pasar argumentos adicionais que controlen a saída do código:

  • ascii_only(predeterminado false) -- escape de caracteres Unicode en cadeas e expresións regulares (afecta ás directivas con caracteres non ascii que non son válidos)

  • beautify(predeterminado true) -- se realmente embelece a saída. Ao pasar -bisto establecerase como verdadeiro, pero pode que teñas que pasar -bmesmo cando queiras xerar código minificado, para especificar argumentos adicionais, para que poidas utilizalo -b beautify=falsepara anulalo.

  • braces(predeterminado false) -- sempre insira chaves nas instrucións if, for, ou , aínda que o seu corpo sexa unha única instrución do.whilewith

  • comments(predeterminado false) -- pase trueou "all"para conservar todos os comentarios, "some"para conservar algúns comentarios, unha cadea de expresións regulares (por exemplo, /^!/) ou unha función.

  • indent_level(predeterminado 4)

  • indent_start(predeterminado 0) -- prefixo todas as liñas con tantos espazos

  • inline_script(predeterminado true) -- escape comentarios HTML e a barra inclinada nas ocorrencias de </script>en cadeas

  • keep_quoted_props(predeterminado false) -- cando está activado, impide eliminar as comiñas dos nomes de propiedade nos literais de obxecto.

  • max_line_len(predeterminado false) -- lonxitude máxima da liña (para o código feo)

  • preamble(predeterminado null) -- cando se pasa debe ser unha cadea e antepoñerase literalmente á saída. O mapa de orixe axustarase para este texto. Pódese usar para inserir un comentario que conteña información de licenza, por exemplo.

  • preserve_line(predeterminado false) -- pasa truepara conservar liñas, pero só funciona se beautifyestá configurado como false.

  • quote_keys(predeterminado false) -- pase truepara citar todas as claves en obxectos literais

  • quote_style(predeterminado 0) -- estilo de comiña preferido para as cadeas (afecta tamén aos nomes e ás directivas das propiedades citadas):

    • 0-- prefire comiñas dobres, cambia a comiñas simples cando hai máis comiñas dobres na propia cadea. 0é o mellor para o tamaño do gzip.
    • 1-- use sempre comiñas simples
    • 2-- use sempre comiñas dobres
    • 3-- use sempre as comiñas orixinais
  • semicolons(predeterminado true) -- declaracións separadas con punto e coma. Se pasa, falsesempre que sexa posible, utilizaremos unha liña nova en lugar de punto e coma, o que dará lugar a unha saída máis lexible de código feo (o tamaño antes de gzip pode ser menor; o tamaño despois de gzip é insignificantemente maior).

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

  • webkit(predeterminado false) -- habilite as solucións para os erros de WebKit. Os usuarios de PhantomJS deben establecer esta opción en true.

  • width(predeterminado 80) -- só ten efecto cando o embelecemento está activado, isto especifica un ancho de liña (orientativo) que o embelecedor tentará obedecer. Refírese ao ancho do texto da liña (excluíndo a sangría). Non funciona moi ben actualmente, pero fai que o código xerado por UglifyJS sexa máis lexible.

  • wrap_iife(predeterminado false) -- pase truepara envolver expresións de función invocadas inmediatamente. Consulte #640 para obter máis detalles.

Varios

Podes pasar --commentspara conservar certos comentarios na saída. Por defecto, manterá os comentarios de estilo JSDoc que conteñan "@preserve", "@license" ou "@cc_on" (compilación condicional para IE). Podes pasar --comments allpara manter todos os comentarios ou unha expresión regular de JavaScript válida para manter só os comentarios que coincidan con esta expresión regular. Por exemplo, --comments /^!/ manterase comentarios como /*! Copyright Notice */.

Teña en conta, non obstante, que pode haber situacións nas que se perdan comentarios. Por exemplo:

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

Aínda que teña "@preserve", o comentario perderase porque a función interna g(que é o nodo AST ao que está conectado o comentario) é descartada polo compresor como non se fai referencia.

Os comentarios máis seguros onde colocar información de copyright (ou outra información que se debe gardar na saída) son os comentarios adxuntos aos nodos de nivel superior.

A unsafe compressopción

Permite algunhas transformacións que poden romper a lóxica do código nalgúns casos artificiais, pero deberían estar ben para a maioría do código. Quizais queiras probalo no teu propio código, debería reducir o tamaño reducido. Isto é o que ocorre cando esta marca está activada:

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

Conditional compilation

Podes usar o interruptor --define( -d) para declarar as variables globais que UglifyJS asumirá como constantes (a non ser que se defina no ámbito). Por exemplo, se pasas --define DEBUG=falseentón, xunto coa eliminación do código morto, UglifyJS descartará o seguinte da saída:

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

Podes especificar constantes aniñadas en forma de --define env.DEBUG=false.

UglifyJS avisará de que a condición é sempre falsa e de que se solta o código inalcanzable; polo momento non hai opción para desactivar só este aviso específico, pode pasar warnings=falsepara desactivar todos os avisos.

Outra forma de facelo é declarar os teus globais como constantes nun ficheiro separado e incluílo na compilación. Por exemplo, podes ter un build/defines.jsficheiro co seguinte:

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

e crea o teu código así:

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

UglifyJS notará as constantes e, dado que non se poden alterar, avaliará as referencias a elas co propio valor e deixará caer o código inalcanzable como é habitual. A compilación conterá as constdeclaracións se as usas. Se estás dirixido a ambientes < ES6 que non not support const, usar varcon reduce_vars(activado por defecto) debería ser suficiente.

Conditional compilation API

Tamén podes usar a compilación condicional a través da API programática. Coa diferenza de que o nome da propiedade é global_defse é unha propiedade do 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 substituír un identificador por unha expresión arbitraria non constante é necesario prefixar a global_defschave con "@"para indicar a UglifyJS que analice o valor como 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");'

En caso contrario, substituirase como literal de cadea:

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 conminify()

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

A transversal e a transformación da AST nativa pódense realizar mediante TreeWalkere TreeTransformer respectivamente.

ESTree / SpiderMonkey AST

UglifyJS ten o seu propio formato de árbore de sintaxe abstracta; por razóns prácticas non podemos cambiar facilmente a usar o SpiderMonkey AST internamente. Non obstante, UglifyJS ten agora un conversor que pode importar un SpiderMonkey AST.

Por exemplo , Acorn é un analizador súper rápido que produce un SpiderMonkey AST. Ten unha pequena utilidade CLI que analiza un ficheiro e volca o AST en JSON na saída estándar. Para usar UglifyJS para modificar e comprimir isto:

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

A -p spidermonkeyopción indica a UglifyJS que todos os ficheiros de entrada non son JavaScript, senón código JS descrito en SpiderMonkey AST en JSON. Polo tanto, non usamos o noso propio analizador neste caso, senón que transformamos ese AST no noso AST interno.

Use Acorn for parsing

Máis por diversión, engadín a -p acornopción que usará Acorn para facer todo o análise. Se pasas esta opción, UgliifyJS fará require("acorn").

Acorn é moi rápido (por exemplo, 250 ms en lugar de 380 ms nalgún código de 650 K), pero converter a árbore SpiderMonkey que produce Acorn leva outros 150 ms, polo que en total é un pouco máis que usar o propio analizador de UglifyJS.

Uglify Fast Minify Mode

Non é moi coñecido, pero a eliminación de espazos en branco e a manipulación de símbolos representan o 95 % da redución de tamaño do código reducido para a maioría de JavaScript, non as transformacións de código elaboradas. Pódese simplemente desactivar compresspara acelerar as compilacións de Uglify de 3 a 4 veces. Desta forma rápida mangle... O único modo Uglify ten velocidades de redución e tamaños gzip comparables a butternut:

d3.js reducir o tamaño tamaño gzip tempo reducido (segundos)
orixinal 451.131 108.733 -
uglify-js@3.0.24 mangle=falso, comprimir=falso 316.600 85.245 0,70
uglify-js@3.0.24 mangle=true, comprimir=false 220.216 72.730 1.13
butternut@0.4.6 217.568 72.738 1.41
uglify-js@3.0.24 mangle=true, comprimir=true 212.511 71.560 3.36
babili@0.1.4 210.713 72.140 12.64

Para activar o modo de minificación rápida desde a CLI, use:

1
uglifyjs file.js -m

Para activar o modo de minificación rápida coa API, use:

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

Mapas de orixe e depuración

Sábese que varias compresstransformacións que simplifican, reorganizan, integran e eliminan código teñen un efecto adverso na depuración dos mapas fonte. Espérase que o código está optimizado e que moitas veces non son posibles as asignacións xa que algún código xa non existe. Para obter a máxima fidelidade na fonte. a depuración de mapas desactive a opción Uglify compresse só use mangle.

Compiler assumptions

Para permitir mellores optimizacións, o compilador fai varias suposicións:

  • .toString()e .valueOf()non teñen efectos secundarios, e para os obxectos incorporados non se anularon.
  • undefined, NaNe Infinitynon se redefiniron externamente.
  • arguments.callee, arguments.callere Function.prototype.callernon se usan.
  • O código non espera que o contido Function.prototype.toString()ou Error.prototype.stacksexa algo en particular.
  • A obtención e configuración de propiedades nun obxecto simple non provoca outros efectos secundarios (usar .watch()ou Proxy).
  • As propiedades do obxecto pódense engadir, eliminar e modificar (non se evitan con , Object.defineProperty(), Object.defineProperties()ou ) .Object.freeze()Object.preventExtensions()Object.seal()