Módulo comunitario incrible

UglifyJS 3

UglifyJS é un kit de ferramentas de analizador, reducción, compresor e embelecedor de JavaScript.

Nota:

  • uglify-js@3ten unha API e CLI simplificadas que non son compatibles con versións anterioresuglify-js@2 .
  • A documentación para as 2.xversións de UglifyJS pódese atopar aquí .
  • uglify-js só admite JavaScript (ECMAScript 5).
  • Para minimizar ECMAScript 2015 ou superior, transpile usando ferramentas como Babel .

Instalar

Primeiro asegúrese de ter instalado a última versión de node.js (é posible que deba reiniciar o ordenador despois deste paso).

De NPM para usalo como aplicación de liña de comandos:

1
npm install uglify-js -g

De NPM para uso programático:

1
npm install uglify-js

Uso da liña de comandos

1
uglifyjs [input files] [options]

UglifyJS pode ter varios ficheiros de entrada. Recoméndase que primeiro pase os ficheiros de entrada e despois pase as opcións. UglifyJS analizará os ficheiros de entrada en secuencia e aplicará as opcións 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, UglifyJS lerá de STDIN.

Se queres pasar as túas opcións antes dos ficheiros de entrada, separa as dúas 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 vai a STDOUT.

Opcións do mapa fonte CLI

UglifyJS pode xerar un ficheiro de mapa de orixe, que é moi útil para depurar o seu JavaScript comprimido. Para obter un mapa de orixe, pásao --source-map --output output.js(o mapa de orixe será escrito 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 a URL onde se atopan os ficheiros orixinais.

  • --source-map "url='<URL>'"para especificar a URL onde se pode atopar o mapa de orixe. Se non, UglifyJS supón X-SourceMapque se 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 comprimirase e manipularase file1.jse file2.jsdeixará caer a saída foo.min.jse o mapa de orixe foo.min.js.map. O mapeo de orixe fará referencia a http://foo.com/src/js/file1.jse http://foo.com/src/js/file2.js(de feito, listará 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 comprima o código JS emitido por un compilador como CoffeeScript, o mapeo ao código JS non será moi útil. Pola contra, desexa mapear de novo ao código orixinal (é dicir, CoffeeScript). UglifyJS ten un opción para tomar un mapa de orixe de entrada. Supoñendo que ten un mapeado de CoffeeScript → JS compilado, UglifyJS pode xerar un mapa de CoffeeScript → JS comprimido mapeando cada token do JS compilado á súa localización orixinal.

Para usar esta característica 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 CLI

Debe pasar --compress( -c) para habilitar o compresor. Opcionalmente pode pasar unha lista de opcións de compresión separadas por comas .

As opcións están na forma foo=barou simplemente foo(esta última implica unha opción booleana que desexa establecer true; é efectivamente un atallo para foo=true).

Exemplo:

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

CLI mangle opcións

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

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

  • eval(predeterminado false): manipular os nomes visibles nos ámbitos onde se usan evalou with.

Cando o manglar está activado pero quere evitar que algúns nomes sexan maltratados, pode declarar eses nomes con --mangle reserved- pasar unha lista de nomes separados por comas. Por exemplo:

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

para evitar a require, exportse $nomes sexan alteradas.

CLI nomes de propiedades manipuladas ( --mangle-props)

Nota: ESTO ROBA PROBABLEMENTE O SEU CÓDIGO. Os nomes de propiedades de manipulación son un paso distinto, distinto do mangling de variables. Pásao --mangle-propspara habilitalo. Manipulará todas as propiedades do código de entrada, a excepción das propiedades DOM incorporadas e as propiedades do JavaScript central. 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());

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

Manxa todas as propiedades, agás 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._());

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

Combinando opcións de propiedades 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 de utilidade, evitamos manexar nomes estándar de JS 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 JS e DOM definidas en varios navegadores. Pase --mangle-props dompropspara desactivar esta función.

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

Cando comprime varios ficheiros usando esta opción, para que traballen xuntos ao final, debemos asegurarnos dalgún xeito de que unha propiedade sexa alterada co mesmo nome en todos eles. Para iso, pass --name-cache filename.json e UglifyJS manterán estas asignacións nun ficheiro que logo pode ser reutilizado. Debería estar inicialmente 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 coherentes entre si en termos de nomes de propiedades maltratadas.

Non é necesario usar a caché de nomes se comprime todos os ficheiros nunha soa chamada a UglifyJS.

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

Usando o nome da propiedade citado ( o["foo"]) resérvase o nome da propiedade ( foo) de xeito que non se manipule ao longo de 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 manexar nomes de propiedades sen ocultalos completamente. Por exemplo, a propiedade o.foo faríalle falta o._$foo$_con esta opción. Isto permite o manexo de propiedades dunha gran base de código mentres aínda podes depurar o código e identificar onde o mangle está rompendo 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 pode pasar un sufixo personalizado usando --mangle-props debug=XYZ. Este sería, entón mangle o.fooa o._$foo$XYZ_. Pode cambiar este cada vez que compilar un guión para identificar como unha propiedade quedou mutilado. Unha técnica é pasar un número aleatorio de cada compilación para simular desconfiguração cambiando con diferentes entradas (por exemplo, ao actualizar o script de entrada con novas propiedades) e para axudar a identificar erros como escribir claves manipuladas no almacenamento.

Referencia API

Supoñendo a instalación a través de NPM, pode cargar UglifyJS na súa aplicación así:

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()habilitará 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}

Pode facer minifymáis dun ficheiro JavaScript á vez usando un obxecto para o primeiro argumento onde as claves son nomes de ficheiro 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 manter 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 de 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 da API `uglify-js@2.x, the 3.x` non produce erros. Para lograr un efecto similar pódese facer o seguinte:

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

Minimiza as opcións

  • warnings(predeterminado false): pase truepara devolver os avisos do compresor result.warnings. Use o valor "verbose"para avisos máis detallados.

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

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

  • mangle(predeterminado true): pasa falsepara omitir nomes de manipulación ou pasa un obxecto para especificar as opcións de manipulación (ver máis abaixo).

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

  • sourceMap(por defecto false): pasa un obxecto se queres especificar as opcións do mapa de orixe .

  • toplevel(por defecto false): confórmase truese desexa habilitar a variable de nivel superior e o nome da función e eliminar as variables e funcións non utilizadas.

  • nameCache(Default null) -pass un obxecto branco {}ou un usado anteriormente nameCacheobxecto se quere variables e propiedade nomes de caché mutilado en varias invocacións de minify()Nota :. esta é unha propiedade de lectura / escritura. minify()Lerá o estado de caché nome deste obxecto e actualiza-lo durante a minificación para que poida ser reutilizada ou persistida externamente polo usuario.

  • ie8(predeterminado false): configura como truepara admitir IE8.

  • keep_fnames(predeterminado false:) -pass truepara evitar descartar ou manipular nomes de funcións. Útil para confiar en código Function.prototype.name.

Minificar 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 é salvo nun arquivo, só regresou en result.map. O valor pasado para sourceMap.urlsó se usa para definir //# sourceMappingURL=out.js.mapen result.code. O valor filenamesó se usa para definir fileatributos (ver especificación ) no ficheiro de mapa de orixe.

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

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

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 o JavaScript compilado e tes un mapa de orixe, 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á a usar a X-SourceMapcabeceira, pode 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

Comprimir opcións

  • arguments(predeterminado :) true: substitúeo 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, permitíndoo os efectos secundarios.

  • comparisons(predeterminado true:): aplique certas optimizacións a nodos binarios, por exemplo !(a <= b) → a > b, intentos de negar nodos 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: pasar truepara descartar as chamadas a console.*funcións. Se desexa deixar unha función específica, como console.infoe / ou conservar os efectos secundarios dos argumentos de función despois de deixar caer a función, use pure_funcsno seu lugar.

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

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

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

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

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

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

  • hoist_vars(por defecto 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 simple / returnstatement:

    • false - o mesmo que 0
    • 0 - forrado en liña
    • 1 - Inline funcións sinxelas
    • 2 - Inline funcións con argumentos
    • 3 - Inline funcións con argumentos e variables
    • true - o mesmo que 3
  • join_vars(predeterminado true:): únete a vardeclaracións consecutivas

  • keep_fargs(predeterminado true:) - Evita que o compresor descarte os argumentos de función non utilizados. Necesítalo para o código no que depende Function.length.

  • keep_fnames(predeterminado :) false- Pase truepara evitar que o compresor descarta os nomes das funcións. Útil para confiar en código Function.prototype.name. Vexa tamén: a keep_fnames opción mangle .

  • keep_infinity(predeterminado :) false: pase truepara evitar que Infinityse comprime 1/0, o que pode causar problemas de rendemento en Chrome.

  • loops(Por defecto true:) - optimizacións para do, whilee forloops de cando podemos estaticamente determinar a condición.

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

  • passes(predeterminado :) 1: o número máximo de veces que se pode executar a compresión. Nalgúns casos, máis dunha pasaxe leva a un código comprimido adicional. Teña presente que máis pasadas levarán máis tempo.

  • properties(predeterminado true:): reescriba o acceso á propiedade mediante 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 seu alcance. Un caso de exemplo aquí, por exemplo var q = Math.floor(a/b). Se a variable qnon é empregado noutros lugares, UglifyJS soltaráo, pero aínda así manterá o Math.floor(a/b), sen saber que fai. Podes pasarlle pure_funcs: [ 'Math.floor' ]para saber que esta función non producirá ningún efecto secundario, caso en que se descartará toda a declaración. a implementación engade algo de sobrecarga (a compresión será máis lenta). Asegúrese de que os símbolos de abaixo pure_funcs tamén están baixo mangle.reservedpara evitar malos tratos.

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

  • reduce_funcs(predeterminado true:): permite inserir funcións dun só uso como expresións de función cando se permite permitir unha maior optimización. Activado de xeito predeterminado. A opción depende de que reduce_vars estea habilitada. Algún código funciona máis rápido no motor Chrome V8 se esta opción está desactivada. Non negativa impacta noutros navegadores importantes.

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

  • sequences(predeterminado true:): únete a frases simples consecutivas usando o operador de comas. Pode definirse como un enteiro positivo para especificar o número máximo de secuencias de comas consecutivas que se xerarán. Se esta opción está definida como trueentón, o sequenceslímite predeterminado é 200. Definir a opción como falseou 0 desactivar. A sequenceslonxitude máis pequena é 2. Un sequencesvalor de 1 é equivalente a truee como tal significa 200. En contadas ocasións, o límite de secuencias predeterminado leva a tempos de compresión moi lentos, nese caso 20recoméndase un valor igual ou inferior.

  • side_effects(predeterminado :) true: pasar falsepara desactivar as funcións que caen potencialmente marcadas como "puras". Unha chamada a 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:): elimina as copias e elimina as switchramas inalcanzables

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

  • top_retain(predeterminado null:): impide a unusedeliminación de funcións e variables de nivel superior específicas (pode ser matriz, separadas por comas, RegExp ou función. Implica toplevel)

  • typeofs(por defecto :) true- Transforma 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:): aplique transformacións "non seguras" (discusión a continuación)

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

  • unsafe_Function(Por defecto false:) - compress e mangle Function(args, code) cando ambos argse codeson cadeas literais.

  • unsafe_math(predeterminado false:): optimice expresións numéricas como 2 * x * 3dentro 6 * x, o que pode dar resultados de punto flotante imprecisos.

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

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

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

  • unused(predeterminado true:): solte funcións e variables sen referencia (as asignacións de variables directas simples non contan como referencias a non ser que estea establecida en "keep_assign")

  • warnings(predeterminado false:): amosa avisos cando elimina código inaccesible ou declaracións non utilizadas, etc.

Opcións de mangar

  • eval(predeterminado false): pasa truea manglar nomes visibles nos ámbitos onde se usan evalou with.

  • keep_fnames(predeterminado false): pase truea non manipular os nomes das funcións. Útil para confiar en código Function.prototype.name. Vexa tamén: a keep_fnames opción de compresión .

  • reserved(Por defecto []) - pasar un BE debía matriz de identificadores que mangling é eliminado Exemplo:. ["foo", "bar"].

  • toplevel(predeterminado false): pásase truea mangle 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: úsase truepara permitir a manipulación das propiedades DOM incorporadas. Non se recomenda anular esta configuración.

  • debug(predeterminado false:) -— Mantéñense os nomes co nome orixinal. Pase unha cadea baleira ""para habilitala ou unha cadea non baleira para establecer o sufixo de depuración.

  • keep_quoted(predeterminado false:) -— Só manipula os nomes de propiedades sen comiñas.

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

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

Opcións de saída

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

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

  • beautify(predeterminado true): se se embelece realmente a saída. Ao pasar -b, establecerase isto como verdadeiro, pero pode que teña que pasar -bincluso cando queira xerar código minificado, para especificar argumentos adicionais, polo que pode usalo -b beautify=falsepara anular.

  • braces(Por defecto false) - Sempre en introducir chaves if, for, do, whileou withdeclaracións, o mesmo o seu corpo e declaración nunha única IF.

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

  • indent_level(predeterminado 4)

  • indent_start(predeterminado 0): prefixa todas as liñas por tantos espazos

  • inline_script(predeterminado true): escapa os comentarios HTML e a barra en aparicións de </script>cadeas

  • keep_quoted_props(predeterminado false): cando está activado, impide eliminar as comiñas dos nomes das propiedades nos literales dos obxectos.

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

  • preamble(por defecto null): cando se pase debe ser unha cadea e adxudicarase literalmente á saída. O mapa fonte axustarase a 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 as liñas, pero só funciona se beautifyestá establecido en false.

  • quote_keys(predeterminado false): pasa truepara citar todas as claves en obxectos literais

  • quote_style(predeterminado 0) - estilo de cita preferido para as cadeas (afecta tamén aos nomes de propiedades e directivas citadas):

    • 0- prefire comiñas dobres, cambia a comiñas simples cando hai máis comiñas dobres na propia cadea. 0é mellor para o tamaño gzip.
    • 1 - emprega sempre comiñas simples
    • 2 - emprega sempre comiñas dobres
    • 3 - use sempre as comiñas orixinais
  • semicolons(predeterminado true): sentencias separadas con punto e coma. Se falseaprobas, sempre que sexa posible, usaremos unha nova liña no canto de punto e coma, o que levará a unha saída máis lexible do código uglificado (o tamaño antes do gzip podería ser menor; o tamaño despois do gzip é insignificantemente maior).

  • shebang(predeterminado true): preservar o shebang #!no preámbulo (scripts bash)

  • webkit(predeterminado false): habilite as solucións para erros de WebKit. Os usuarios de PhantomJS deberían establecer esta opción como true.

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

  • wrap_iife(predeterminado false): pasa truepara axustar expresións de función invocadas inmediatamente. Vexa o número 640 para máis detalles.

Varios

Podes pasar --commentspara conservar certos comentarios na saída. De xeito predeterminado, manterá comentarios ao 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 reexxp de JavaScript válida para manter só os comentarios que coincidan con esta expreg. Por exemplo --comments /^!/ , manterá comentarios como /*! Copyright Notice */.

Non obstante, teña en conta que pode haber situacións nas que se perden 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 ten "@preserve", o comentario perderase porque a función interna g(que é o nodo AST ao que está unido o comentario) é descartada polo compresor xa que non fai referencia.

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

A unsafe compressopción

Permite algunhas transformacións que poden romper a lóxica do código nalgúns casos inventados, pero deberían estar ben para a maioría do código. É posible que 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 o new

Conditional compilation

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

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

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

UglifyJS avisará sobre a condición sempre falsa e sobre a caída de código inalcanzable; polo de agora non hai ningunha opción para desactivar só este aviso específico, pode pasar warnings=falsepara desactivar todos os avisos.

Outro xeito de facelo é declarar os seus globais como constantes nun ficheiro separado e incluílo na compilación. Por exemplo, pode 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 ao valor en si e deixará caer un código inalcanzable como de costume. A compilación conterá as constdeclaracións se as utiliza. Se está dirixido a ambientes <ES6 o que fai non compatible const, usar varcon reduce_vars(activado por defecto) debería ser suficiente.

Conditional compilation API

Tamén pode 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_defsclave con "@"para indicar a UglifyJS que analice o valor como unha 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 substituiríase por 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 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

A transversal e a transformación do AST nativo pódense realizar a través de 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 agora ten 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 descarga o AST en JSON na saída estándar. Para usar UglifyJS para manipular e comprimir:

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

A -p spidermonkeyopción dille a UglifyJS que todos os ficheiros de entrada non son JavaScript, senón o 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álisis. Se aprobas esta opción, fará UglifyJS require("acorn").

A landra é moi rápida (por exemplo, 250 ms no canto de 380 ms nun código de 650 K), pero converter a árbore SpiderMonkey que produce Acorn leva outros 150 ms, polo que en total é algo máis que usar o propio analizador de UglifyJS.

Uglify Fast Minify Mode

Non é ben coñecido, pero os espazos en branco de retirada e símbolo desconfiguração é responsábel por 95% de polo a redución de tamaño en código minified para a maioría dos JavaScript -. Código non elaborar o Transforms pode simplemente desactivar compressa acelerar enfear constrúe por 3 a 4 veces por O este é o RÁPIDO. mangle- O único modo Uglify ten velocidades minify e tamaños gzip comparables a butternut:

d3.js tamaño minify tamaño gzip tempo de minificación (segundos)
orixinal 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 = verdadeiro, comprimir = falso 220.216 72.730 1.13
butternut@0.4.6 217.568 72.738 1,41
uglify-js@3.0.24 mangle = verdadeiro, comprimir = verdadeiro 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 o uso da CLI:

1
uglifyjs file.js -m

Para habilitar o modo de minificación rápida co uso da API:

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

Mapas de orixe e depuración

compressSábese que varias transformacións que simplifican, reorganizan, incorporan e eliminan o código teñen un efecto adverso na depuración con mapas de orixe. Espérase que o código se optimiza e as asignacións a miúdo simplemente non son posibles xa que algún código xa non existe. Para unha maior fidelidade na fonte a depuración de mapas desactiva a compressopción Uglify e só tes que usala 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 substituíron.
  • 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 non Error.prototype.stacksexa nada en particular.
  • Obter e establecer propiedades nun obxecto simple non causa outros efectos secundarios (usando .watch()ou Proxy).
  • Se pode engadir o obxecto Propiedades, eliminado e modificación (non impediu con Object.defineProperty(), Object.defineProperties(), Object.freeze(), Object.preventExtensions()ou Object.seal()).