Mòdul de comunitat impressionant

UglifyJS 3

UglifyJS és un conjunt d’eines d’analitzador, minificador, compressor i embellidor de JavaScript.

Nota:

  • uglify-js@3té una API i CLI simplificades que no són compatibles amb les versions anteriorsuglify-js@2 .
  • La documentació per a les 2.xversions d’ UglifyJS es pot trobar aquí .
  • uglify-js només admet JavaScript (ECMAScript 5).
  • Per minimitzar ECMAScript 2015 o superior, transpileu utilitzant eines com Babel .

Instal·la

Primer, assegureu-vos que heu instal·lat la versió més recent de node.js (és possible que hàgiu de reiniciar l'ordinador després d'aquest pas).

Des de NPM per utilitzar-lo com a aplicació de línia d'ordres:

1
npm install uglify-js -g

Des de NPM per a ús programàtic:

1
npm install uglify-js

Ús de la línia d’ordres

1
uglifyjs [input files] [options]

UglifyJS pot agafar diversos fitxers d'entrada. Es recomana passar primer els fitxers d'entrada i després passar les opcions. UglifyJS analitzarà els fitxers d'entrada en seqüència i aplicarà les opcions de compressió. Els fitxers s'analitzen en el mateix àmbit global, és a dir, una referència d'un fitxer a alguna variable / funció declarada en un altre fitxer coincidirà correctament.

Si no s'especifica cap fitxer d'entrada, UglifyJS llegirà des de STDIN.

Si voleu passar les vostres opcions abans dels fitxers d’entrada, separeu-les amb un guió doble per evitar que s’utilitzin fitxers d’entrada com a arguments d’opció:

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.

Especifiqueu --output( -o) per declarar el fitxer de sortida. En cas contrari, la sortida es dirigeix ​​a STDOUT.

Opcions del mapa font CLI

UglifyJS pot generar un fitxer de mapa d'origen, que és molt útil per depurar el vostre JavaScript comprimit. Per obtenir un mapa d'origen, passeu --source-map --output output.js(el mapa d'origen s'escriurà a output.js.map).

Opcions addicionals:

  • --source-map "filename='<NAME>'" per especificar el nom del mapa d'origen.

  • --source-map "root='<URL>'" per passar l'URL on es poden trobar els fitxers originals.

  • --source-map "url='<URL>'"per especificar l'URL on es pot trobar el mapa d'origen. En cas contrari, UglifyJS assumeix que X-SourceMaps'està utilitzant HTTP i ometrà la //# sourceMappingURL=directiva.

Per exemple:

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

L'esmentat anterior es comprimirà i manipularà file1.jsi file2.js, deixarà caure la sortida foo.min.jsi el mapa d'origen foo.min.js.map. El mapatge d'origen es referirà a http://foo.com/src/js/file1.jsi http://foo.com/src/js/file2.js(de fet, apareixerà http://foo.com/src com a arrel del mapa d'origen i els fitxers originals com js/file1.jsi js/file2.js).

Composed source map

Quan comprimeu el codi JS que va enviar un compilador com ara CoffeeScript, no serà massa útil assignar-lo al codi JS. En comptes d'això, voldríeu tornar a assignar-vos al codi original (és a dir, CoffeeScript). UglifyJS té opció per agafar un mapa d'origen d'entrada. Suposant que teniu un mapatge des de CoffeeScript → JS compilat, UglifyJS pot generar un mapa des de CoffeeScript → JS comprimit assignant tots els testimonis del JS compilat a la seva ubicació original.

Per utilitzar aquesta característica, passeu --source-map "content='/path/to/input/source.map'" o --source-map "content=inline"si el mapa d'origen s'inclou en línia amb les fonts.

Opcions de compressió CLI

Heu de passar --compress( -c) per habilitar el compressor. Opcionalment, podeu passar una llista d' opcions de compressió separades per comes .

Les opcions estan en la forma foo=baro simplement foo(aquesta última implica una opció booleana que vulgueu establir true; és efectivament una drecera foo=true).

Exemple:

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

Opcions de maneig CLI

Per habilitar el mangler heu de passar --mangle( -m). S'admeten les opcions següents (separades per comes):

  • toplevel(per defecte false): manipula els noms declarats a l'abast del nivell superior.

  • eval(per defecte false): manipula els noms visibles als àmbits on s'utilitzen evalo with.

Quan la manipulació està habilitada, però voleu evitar que alguns noms es malmetin, podeu declarar aquests noms amb --mangle reserved- passar una llista de noms separats per comes. Per exemple:

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

per evitar que el require, exportsi $els noms que es canviïn.

Noms de propietats manipulades CLI ( --mangle-props)

Nota: AQUEST PROBABLEMENT TRENCARÀ EL VOSTRE CODI. La manipulació dels noms de propietats és un pas diferent, diferent de la manipulació de noms de variables. Passeu-la --mangle-propsper habilitar-la. Tractarà totes les propietats del codi d'entrada amb l'excepció de les propietats DOM incorporades i les propietats del nucli JavaScript classes. Per exemple:

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

Manegeu totes les propietats (excepte 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());

Mangeu totes les propietats, excepte les reservedpropietats:

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

Manegeu totes les propietats que coincideixin amb 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());

Combinant opcions de propietats 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());

Per tal que això sigui útil, evitem manipular de manera predeterminada els noms JS estàndard ( --mangle-props builtinsper anul·lar).

Es proporciona un fitxer d'exclusió per defecte en el tools/domprops.jsonqual s'han de cobrir la majoria de propietats JS i DOM estàndard definides en diversos navegadors. Passa --mangle-props dompropsper desactivar aquesta funció.

Es pot utilitzar una expressió regular per definir quins noms de propietats s’han de manipular. Per exemple, --mangle-props regex=/^_/només es manipularan els noms de propietats que comencin amb un subratllat.

Quan comprimeu diversos fitxers mitjançant aquesta opció, per tal que puguin treballar junts al final, hem d’assegurar-nos que d’una propietat es converteixi en el mateix nom en tots. Per a això, pass --name-cache filename.json i UglifyJS mantindran aquestes assignacions en que es pot tornar a utilitzar. Inicialment hauria d'estar buit. Exemple:

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

Ara, part1.jsi part2.jsseran coherents entre si en termes de noms de propietats malmeses.

No és necessari utilitzar la memòria cau de noms si comprimeu tots els fitxers en una sola trucada a UglifyJS.

Tractament de noms sense cometes ( --mangle-props keep_quoted)

Si utilitzeu el nom de la propietat entre cometes ( o["foo"]), es reserva el nom de la propietat ( foo) de manera que no es manipuli al llarg de tot l’escriptura, fins i tot quan s’utilitza amb un estil no citat ( o.foo). Exemple:

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

També podeu passar --mangle-props debugper manipular noms de propietats sense ocultar-los completament. Per exemple, la propietat o.foo es modificaria o._$foo$_amb aquesta opció. Això permet la manipulació de propietats d'una base de codis gran mentre es pot depurar el codi i identificar on la manipulació està trencant coses.

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

També podeu passar un sufix personalitzat mitjançant --mangle-props debug=XYZ. Això es modificaria o.fooa o._$foo$XYZ_. Podeu canviar-ho cada vegada que compileu un script per identificar com es va manipular una propietat. Una tècnica consisteix a passar un número aleatori a cada compilació per simular el canvi de manglar amb diferents. entrades (per exemple, en actualitzar l'script d'entrada amb noves propietats), i per ajudar a identificar errors com escriure claus manipulades a l'emmagatzematge.

Referència de l'API

Suposant la instal·lació mitjançant NPM, podeu carregar UglifyJS a la vostra aplicació així:

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

Hi ha una única funció d'alt nivell minify(code, options), que realitzarà totes les fases de minificació d'una manera configurable. Per defecte minify()activarà les opcions compress i mangle. Exemple:

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}

Podeu fer minifymés d’un fitxer JavaScript alhora utilitzant un objecte per al primer argument on les claus són noms de fitxers i els valors són codi font:

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

L' toplevelopció:

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

L' nameCacheopció:

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

Podeu mantenir la memòria cau de noms al sistema de fitxers de la següent 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 exemple d'una combinació d' minify()opcions:

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

Per produir 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 exemple d'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 diferència de l' API `uglify-js@2.x, the 3.x` no genera errors. Per aconseguir un efecte similar es pot fer el següent:

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

Minimitza les opcions

  • warnings(per defecte false): passa trueper tornar els avisos del compressor result.warnings. Utilitzeu el valor "verbose"per obtenir avisos més detallats.

  • parse(per defecte {}): passeu un objecte si voleu especificar algunes opcions d’anàlisi addicionals .

  • compress(per defecte {}): passa falseper ometre la compressió totalment. Passa un objecte per especificar opcions de compressió personalitzades .

  • mangle(per defecte true): passa falseper ometre els noms manipulats o passa un objecte per especificar les opcions de manipulació (vegeu més avall).

    • mangle.properties(per defecte false): una subcategoria de l'opció mangle. Passa un objecte per especificar opcions de propietats mangle personalitzades .
  • output(per defecte null): passeu un objecte si voleu especificar opcions de sortida addicionals . Els valors predeterminats estan optimitzats per obtenir la millor compressió.

  • sourceMap(per defecte false): passeu un objecte si voleu especificar les opcions del mapa d'origen .

  • toplevel(per defecte false): es defineix truesi voleu habilitar la variable de nivell superior i la manipulació del nom de la funció i deixar anar variables i funcions no utilitzades.

  • nameCache(per defecte null): passeu un objecte buit {}o un nameCacheobjecte utilitzat anteriorment si voleu emmagatzemar a la memòria cau noms de variables i propietats en diverses invocacions de minify(). Nota: es tracta d'una propietat de lectura / escriptura. minify()llegirà l'estat de memòria cau d'aquest objecte i l'actualitzarà durant la minificació perquè l'usuari pugui reutilitzar-la o persistir-la externament.

  • ie8(per defecte false) -estableix per truedonar suport a IE8.

  • keep_fnames(per defecte:) false-pass trueper evitar descartar o manipular noms de funcions. Útil per a la confiança en el codi Function.prototype.name.

Minimitza l'estructura d'opcions

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

Per generar un mapa d'origen:

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

Tingueu en compte que el mapa d'origen no es desa en un fitxer, només s'hi torna result.map. El valor que es transmet sourceMap.urlnomés s'utilitza per establir //# sourceMappingURL=out.js.map-hi result.code. El valor de filenamenomés s'utilitza per establir l' fileatribut (vegeu l'especificació ) al fitxer de mapa d'origen.

Podeu configurar l'opció sourceMap.urlde ser "inline"i el mapa d'origen s'afegirà al codi.

També podeu especificar la propietat sourceRoot per incloure-la al mapa font:

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 comprimeu JavaScript compilat i en teniu un mapa d'origen, podeu utilitzar 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 feu servir la X-SourceMapcapçalera, podeu ometre sourceMap.url.

Opcions d’anàlisi

  • bare_returns(per defecte false): admet returndeclaracions de nivell superior

  • html5_comments(per defecte true)

  • shebang(per defecte true): suport #!commandcom a primera línia

Opcions de compressió

  • arguments(per defecte :) true: substituïu-lo arguments[index]pel nom del paràmetre de la funció sempre que sigui possible.

  • booleans(predeterminat true:): diverses optimitzacions per al context booleà, per exemple!!a ? b : c → a ? b : c

  • collapse_vars(predeterminat true:): replega variables no constants d'un sol ús, si els efectes secundaris ho permeten.

  • comparisons(per defecte true:): apliqueu certes optimitzacions a nodes binaris, per exemple !(a <= b) → a > b, intents de negar nodes binaris, per exemple, a = !b && !c && !d && !e → a=!(b||c||d||e)etc.

  • conditionals(per defecte true:): apliqueu optimitzacions per a if-s i expressions condicionals

  • dead_code(per defecte true:): elimineu el codi inaccessible

  • drop_console(predeterminat :) false- Passa trueper descartar les trucades a console.*funcions. Si voleu deixar una funció específica, com ara console.infoi / o conservar els efectes secundaris dels arguments de funció després de deixar de fer una trucada, utilitzeu-la pure_funcsen lloc.

  • drop_debugger(per defecte :) true: elimina les debugger;sentències

  • evaluate(per defecte true:): intenteu avaluar expressions constants

  • expression(per defecte :) false- Passa trueper conservar els valors de finalització de les sentències de terminal sense return, per exemple, a bookmarklets.

  • global_defs(per defecte :){} : vegeu la compilació condicional

  • hoist_funs(predeterminat false:) - declaracions de funció d'elevació

  • hoist_props(per defecte true:): aixeca les propietats dels objectes constants i els literals de la matriu en variables regulars subjectes a un conjunt de restriccions. Per exemple: var o={p:1, q:2}; f(o.p, o.q);es converteix a f(1, 2);. Nota: hoist_props funciona millor amb mangleactivat, l' compressopció passesestablerta a 2o superior i l' compressopció toplevelactivada.

  • hoist_vars(predeterminat false:) - vardeclaracions d' elevació (això és false per defecte perquè sembla que augmenta la mida de la sortida en general)

  • if_return(predeterminat true:): optimitzacions per a if / return i if / continue

  • inline(predeterminat true:): trucades en línia per funcionar amb simple / returnstatement:

    • false - el mateix que 0
    • 0 - discapacitat en línia
    • 1 - Funcions senzilles en línia
    • 2 - funcions en línia amb arguments
    • 3 - funcions en línia amb arguments i variables
    • true - el mateix que 3
  • join_vars(per defecte true:): unir vardeclaracions consecutives

  • keep_fargs(predeterminat true:): impedeix que el compressor descarti els arguments de funció no utilitzats. Ho necessiteu per al codi en què es basa Function.length.

  • keep_fnames(predeterminat :) false: passa trueper evitar que el compressor descarti els noms de les funcions. Útil per a la confiança del codi Function.prototype.name. Vegeu també: l' keep_fnames opció mangle .

  • keep_infinity(predeterminat :) false: passa trueper evitar que Infinityes comprimeixi 1/0, cosa que pot causar problemes de rendiment a Chrome.

  • loops(Per defecte true:) - optimitzacions per a do, whilei forbucles quan podem determinar la condició estàtica.

  • negate_iife(per defecte true:): anuleu "Expressions de funció de trucada immediata", on es descarta el valor de retorn, per evitar els parens que inseriria el generador de codi.

  • passes(predeterminat :) 1: el nombre màxim de vegades que es pot executar la compressió. En alguns casos, més d'una passada condueix a un codi comprimit addicional. Tingueu en compte que més passades trigaran més temps.

  • properties(predeterminat true:): reescriviu l'accés a la propietat mitjançant la notació de punts, per exemplefoo["bar"] → foo.bar

  • pure_funcs(predeterminat :) null- Podeu passar una matriu de noms i UglifyJS assumirà que aquestes funcions no produeixen efectes secundaris. PERILL: no comprovarà si el nom es redefineix en l'àmbit. Un cas d'exemple aquí, per exemple var q = Math.floor(a/b). Si la variable qno és utilitzat en un altre lloc, UglifyJS el deixarà, però continuarà mantenint el fitxer Math.floor(a/b), sense saber què fa. Podeu passar pure_funcs: [ 'Math.floor' ]per fer-li saber que aquesta funció no produirà cap efecte secundari, en aquest cas es descartaria tota la declaració. la implementació afegeix una mica de sobrecàrrega (la compressió serà més lenta). Assegureu-vos que els símbols que pure_funcs hi ha a sota també estan sota mangle.reservedper evitar malgastar.

  • pure_getters(per defecte :) "strict": si ho feu true, UglifyJS assumirà que l'accés a la propietat de l'objecte (per exemple, foo.baro foo["bar"]) no té cap efecte secundari. Especifiqueu "strict"que es tracti foo.barcom a lliure d'efectes secundaris només quan foono es llançarà, és a dir, no nullo undefined.

  • reduce_funcs(predeterminat true:): permet que les funcions d'un sol ús s'inclinin com a expressions de funció quan es permeti, permetent una optimització addicional. S'habilita de manera predeterminada. L'opció depèn que reduce_vars estigui activada. Alguns codis s'executen més ràpidament al motor Chrome V8 si aquesta opció està desactivada. afecten altres navegadors importants.

  • reduce_vars(per defecte true:): millorar l'optimització de les variables assignades i utilitzades com a valors constants.

  • sequences(predeterminat true:): uneix sentències simples consecutives mitjançant l'operador de comes. Es pot establir en un enter positiu per especificar el nombre màxim de seqüències de comes consecutives que es generaran. Si aquesta opció s'estableix en true, el sequenceslímit per defecte és 200. Estableix l'opció a falseo 0 per desactivar-lo. La sequenceslongitud més petita és 2. El sequencesvalor de 1 es pot obtenir com a equivalent truei, com a tal, significa 200. En poques ocasions, el límit de seqüències per defecte comporta temps de compressió molt lents, en aquest cas 20es recomana un valor igual o inferior.

  • side_effects(predeterminat :) true: passa falseper desactivar les funcions que poden deixar caure marcades com a "pura". Una trucada a una funció es marca com a "pura" si una anotació de comentari /*@__PURE__*/o /*#__PURE__*/immediatament precedeix la trucada. Per exemple:/*@__PURE__*/foo();

  • switches(predeterminat true:): desdobleu i elimineu les switchbranques inaccessibles

  • toplevel(per defecte false:): deixeu anar funcions sense referència ( "funcs") i / o variables ( "vars") a l'abast del nivell superior ( falseper defecte, trueper deixar anar funcions i variables sense referència)

  • top_retain(per defecte null:): evita que funcions i variables de unusednivell superior específiques s'eliminin (poden ser matriu, separades per comes, RegExp o funció. Implica toplevel)

  • typeofs(per defecte :) true: es transforma typeof foo == "undefined"en foo === void 0. Nota: es recomana establir aquest valor per falsea IE10 i versions anteriors a causa de problemes coneguts.

  • unsafe(per defecte false:): apliqueu transformacions "no segures" (debat a continuació)

  • unsafe_comps(per defecte :) false: comprimeix expressions com a <= bsuposant que cap dels operands pot ser (coaccionat a) NaN.

  • unsafe_Function(Per defecte false:) - Comprimir i el mangle Function(args, code) quan tots dos argsi codesón literals de cadena.

  • unsafe_math(per defecte false:): optimitzeu expressions numèriques com 2 * x * 3a 6 * x, que poden donar resultats de punt flotant imprecisos.

  • unsafe_proto(per defecte false:): optimitzeu expressions com Array.prototype.slice.call(a)a[].slice.call(a)

  • unsafe_regexp(per defecte false:): permet substituir variables amb RegExpvalors de la mateixa manera que si fossin constants.

  • unsafe_undefined(per defecte false:): substitueix void 0si hi ha una variable anomenada undefineda l'abast (el nom de la variable es manipularà, normalment es reduirà a un sol caràcter)

  • unused(per defecte true:): elimineu funcions i variables sense referència (les assignacions de variables directes simples no compten com a referències tret que s'estableixi en "keep_assign")

  • warnings(predeterminat false:): mostra avisos quan deixeu anar codi inaccessible o declaracions no utilitzades, etc.

Opcions Mangle

  • eval(per defecte false): passa truea manglar els noms visibles als àmbits on s'utilitzen evalo with.

  • keep_fnames(per defecte false): passa truea no manipular els noms de les funcions. Útil per confiar en el codi Function.prototype.name. Vegeu també: l' keep_fnames opció de compressió .

  • reserved(Per defecte []) - Pass AN ser netejats han Matriu d'identificadors que mangling s'exclou de l'Exemple:. ["foo", "bar"].

  • toplevel(per defecte false): passa truea noms de mangle declarats a l'abast del nivell superior.

Exemples:

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(predeterminat :) false- Utilitzeu-ho trueper permetre la manipulació de propietats DOM integrades. No es recomana anul·lar aquesta configuració.

  • debug(per defecte false:) -— Mantingueu els noms amb el nom original. Passeu una cadena buida ""per activar-la o una cadena no buida per establir el sufix de depuració.

  • keep_quoted(per defecte false:) -— Només manipular els noms de propietats sense cometes.

  • regex(per defecte null:) -— Passa un literal RegExp a només manipular noms de propietats que coincideixin amb l'expressió regular.

  • reserved(per defecte []:): no manipuleu els noms de propietats que apareixen a la reservedmatriu.

Opcions de sortida

El generador de codi intenta generar el codi més curt possible per defecte. En cas que vulgueu una sortida embellida, pass --beautify( -b). Opcionalment, podeu passar arguments addicionals que controlin la sortida del codi:

  • ascii_only(per defecte false): escapa dels caràcters Unicode de cadenes i d'expressions regulars (afecta les directrius amb caràcters no ascii que no són vàlids)

  • beautify(per defecte true): si voleu embellir la sortida. Si es passa -b, s'establirà a true, però és possible que hagueu de passar -bfins i tot quan vulgueu generar codi minificat, per especificar arguments addicionals, de manera que podeu -b beautify=falsesubstituir-lo.

  • braces(Per defecte false) - Sempre en inserir claus if, for, do, whileo withdeclaracions, el fins i tot el seu cos és la declaració UN SOL SI.

  • comments(per defecte false): passa trueo "all"conserva tots els comentaris, "some"conserva alguns comentaris, una cadena d'expressió regular (per exemple /^!/) o una funció.

  • indent_level(per defecte 4)

  • indent_start(per defecte 0): prefixeu totes les línies per tants espais

  • inline_script(per defecte true): escapa els comentaris HTML i la barra inclosa en les aparicions de les </script>cadenes

  • keep_quoted_props(per defecte false): quan està activat, impedeix eliminar les cometes dels noms de propietats als literals dels objectes.

  • max_line_len(per defecte false): longitud màxima de la línia (per al codi uglificat)

  • preamble(per defecte null): quan es passa, ha de ser una cadena i s'anirà prèviament a la sortida. El mapa d'origen s'ajustarà a aquest text. Per exemple, es pot utilitzar per inserir un comentari que contingui informació sobre llicències.

  • preserve_line(per defecte false): passa trueper conservar les línies, però només funciona si beautifyestà definit a false.

  • quote_keys(per defecte false): passa trueper citar totes les claus dels objectes literals

  • quote_style(per defecte 0): estil de cometes preferit per a les cadenes (també afecta els noms de propietats i directives):

    • 0- prefereix les cometes dobles, canvia a cometes simples quan hi ha més cometes dobles a la pròpia cadena. 0és millor per a la mida gzip.
    • 1 - utilitzeu sempre cometes simples
    • 2 - utilitzeu sempre cometes dobles
    • 3 - utilitzeu sempre les cometes originals
  • semicolons(per defecte true): sentències separades amb punts i coma. Si ho falseaprovem, sempre que sigui possible, farem servir una línia nova en lloc de punt i coma, que donarà lloc a una sortida més llegible del codi uglificat (la mida abans que gzip sigui menor; la mida després de gzip sigui insignificantment més gran).

  • shebang(per defecte true): preservar el shebang #!al preàmbul (scripts bash)

  • webkit(per defecte false): activeu les solucions per als errors de WebKit. Els usuaris de PhantomJS haurien d'establir aquesta opció a true.

  • width(predeterminat 80): només té efecte quan l'embelliment està activat, especifica una amplada de línia (orientativa) que l'embellidor intentarà obeir. Es refereix a l'amplada del text de la línia (excloent el sagnat). Actualment no funciona molt bé , però fa que el codi generat per UglifyJS sigui més llegible.

  • wrap_iife(per defecte false): passa trueper embolicar expressions de funció invocades immediatament. Consulteu el # 640 per obtenir més detalls.

Divers

Podeu passar --commentsper conservar certs comentaris a la sortida. Per defecte, mantindrà els comentaris a l'estil JSDoc que continguin "@preserve", "@license" o "@cc_on" (compilació condicional per a IE). Podeu passar --comments allper conservar tots els comentaris o una reexpressió de JavaScript vàlida per conservar només els comentaris que coincideixin amb aquesta expressió. Per exemple, --comments /^!/ es mantindran els comentaris com /*! Copyright Notice */.

Tingueu en compte, però, que hi pot haver situacions en què es perdin comentaris. Per exemple:

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

Tot i que té "@preserve", el comentari es perdrà perquè gel compressor descarta la funció interna (que és el node AST al qual està unit el comentari) perquè no es fa referència.

Els comentaris més segurs on col·locar la informació de drets d'autor (o altra informació que cal conservar a la sortida) són comentaris adjunts als nodes de nivell superior.

L’ unsafe compressopció

Permet algunes transformacions que poden trencar la lògica del codi en certs casos artificiosos, però haurien d'anar bé per a la majoria de codis. És possible que vulgueu provar-ho amb el vostre propi codi, hauria de reduir la mida reduïda. Això és el que passa quan aquesta 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 (...) → descartem el new

Conditional compilation

Podeu utilitzar el commutador --define( -d) per declarar les variables globals que UglifyJS assumirà constants (tret que es defineixin a l'abast). Per exemple, si ho feu --define DEBUG=false, juntament amb l'eliminació de codi mort UglifyJS descartarà el següent de la sortida:

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

Podeu especificar constants imbricades en forma de --define env.DEBUG=false.

UglifyJS avisarà sobre la condició sempre falsa i sobre la caiguda de codi inaccessible; ara per ara no hi ha cap opció per desactivar només aquest advertiment específic; podeu passar warnings=falseper desactivar tots els avisos.

Una altra manera de fer-ho és declarar els vostres globals com a constants en un fitxer separat i incloure-los a la compilació. Per exemple, podeu tenir un build/defines.jsfitxer amb el següent:

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

i creeu el vostre codi així:

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

UglifyJS notarà les constants i, com que no es poden modificar, avaluarà les referències al valor en si mateix i deixarà anar el codi inaccessible com de costum. La compilació contindrà les constdeclaracions si les feu servir. Si esteu orientant els entorns <ES6, no és compatible const, utilitzar varamb reduce_vars(activat per defecte) hauria de ser suficient.

Conditional compilation API

També podeu utilitzar la compilació condicional mitjançant l'API programàtica. Amb la diferència que el nom de la propietat és global_defsi és una propietat de compressor:

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

Per substituir un identificador per una expressió arbitrària no constant, cal posar un prefix de la global_defsclau "@"per indicar a UglifyJS que analitzi el valor com a expressió:

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

En cas contrari, es substituiria com a 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");'

Utilitzant Uglify AST amb 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 transformació i la transformació de l'AST nativa es poden realitzar a través de TreeWalkeri TreeTransformer respectivament.

ESTree / SpiderMonkey AST

UglifyJS té el seu propi format d'arbre de sintaxi abstracte; per raons pràctiques no podem canviar fàcilment a fer servir SpiderMonkey AST internament, però ara UglifyJS té un convertidor que pot importar un SpiderMonkey AST.

Per exemple, Acorn és un analitzador súper ràpid que produeix un SpiderMonkey AST. Té una petita utilitat CLI que analitza un fitxer i bolca l'AST en JSON a la sortida estàndard. Per utilitzar UglifyJS per manipular i comprimir:

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

L' -p spidermonkeyopció indica a UglifyJS que tots els fitxers d'entrada no són JavaScript, sinó el codi JS descrit a SpiderMonkey AST a JSON. Per tant, en aquest cas no fem servir el nostre propi analitzador, sinó que només transformem aquest AST en el nostre AST intern.

Use Acorn for parsing

Més per diversió, he afegit l’ -p acornopció que utilitzarà Acorn per fer tot l’anàlisi. Si passa aquesta opció, UglifyJS ho farà require("acorn").

Acorn és realment ràpid (per exemple, 250 ms en lloc de 380 ms en algun codi de 650K), però convertir l'arbre SpiderMonkey que produeix Acorn triga 150 ms, de manera que, en total, és una mica més que fer servir el propi analitzador d'UglifyJS.

Uglify Fast Minify Mode

No és ben coneguda, però els espais en blanc d'eliminació i Symbol mangling representa el 95% de al La reducció de mida en el codi minified MOST JavaScript -. Codi no Elaborar les transformacions simplement es pot desactivar compressper accelerar retreure es basa en un 3 a 4 vegades An al això és el FAST. mangle- només el mode Uglify té velocitats de minificació i mides gzip comparables a butternut:

d3.js reduir la mida mida gzip temps de reducció (segons)
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

Per habilitar el mode de minificació ràpida des de l'ús de la CLI:

1
uglifyjs file.js -m

Per activar el mode de minificació ràpida amb l'ús de l'API:

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

Mapes d'origen i depuració

compressSe sap que diverses transformacions que simplifiquen, reordenen, integren i eliminen el codi tenen un efecte advers en la depuració amb mapes d'origen. Això s'espera ja que el codi s'optimitza i les assignacions sovint simplement no són possibles, ja que ja no existeix cap codi. Per obtenir una fidelitat màxima la depuració de mapes desactiva l' compressopció Uglify i només cal utilitzar-la mangle.

Compiler assumptions

Per permetre millors optimitzacions, el compilador fa diverses suposicions:

  • .toString()i .valueOf()no tenen efectes secundaris, i per als objectes integrats no s’han anul·lat.
  • undefined, NaNi Infinityno s'han redefinit externament.
  • arguments.callee, arguments.calleri Function.prototype.callerno s’utilitzen.
  • El codi no espera que el contingut Function.prototype.toString()ni Error.prototype.stacksigui cap cosa en particular.
  • Obtenir i establir propietats en un objecte normal no causa altres efectes secundaris (utilitzant .watch()o Proxy).
  • Poden afegir-se l'objecte Properties, eliminat i modificat (no impedit amb Object.defineProperty(), Object.defineProperties(), Object.freeze(), Object.preventExtensions()o Object.seal()).