UglifyJS 3
UglifyJS es un conjunto de herramientas de analizador, minificador, compresor y embellecimiento de JavaScript.
Nota:
uglify-js@3
tiene una API y una CLI simplificadas que no son compatibles con versiones anterioresuglify-js@2
.- La documentación de las
2.x
versiones de UglifyJS se puede encontrar aquí . uglify-js
solo es compatible con JavaScript (ECMAScript 5).- Para minimizar ECMAScript 2015 o superior, transpile usando herramientas como Babel .
Instalar en pc
Primero asegúrese de haber instalado la última versión de node.js (es posible que deba reiniciar su computadora después de este paso).
Desde NPM para usar como una aplicación de línea de comandos:
1npm install uglify-js -g
De NPM para uso programático:
1npm install uglify-js
Uso de la línea de comandos
1uglifyjs [input files] [options]
UglifyJS puede tomar varios archivos de entrada. Se recomienda que primero pase los archivos de entrada y luego las opciones. UglifyJS analizará los archivos de entrada en secuencia y aplicará las opciones de compresión. Los archivos se analizan en el mismo alcance global, es decir, una referencia de un archivo a alguna variable / función declarada en otro archivo coincidirá correctamente.
Si no se especifica ningún archivo de entrada, UglifyJS leerá desde STDIN.
Si desea pasar sus opciones antes que los archivos de entrada, separe los dos con un guión doble para evitar que los archivos de entrada se utilicen como argumentos de opción:
1uglifyjs --compress --mangle -- input.js
Command line options
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 -h, --help Print usage information.
`--help options` for details on available options.
-V, --version Print version number.
-p, --parse <options> Specify parser options:
`acorn` Use Acorn for parsing.
`bare_returns` Allow return outside of functions.
Useful when minifying CommonJS
modules and Userscripts that may
be anonymous function wrapped (IIFE)
by the .user.js engine `caller`.
`expression` Parse a single expression, rather than
a program (for parsing JSON).
`spidermonkey` Assume input files are SpiderMonkey
AST format (as JSON).
-c, --compress [options] Enable compressor/specify compressor options:
`pure_funcs` List of functions that can be safely
removed when their return values are
not used.
-m, --mangle [options] Mangle names/specify mangler options:
`reserved` List of names that should not be mangled.
--mangle-props [options] Mangle properties/specify mangler options:
`builtins` Mangle property names that overlaps
with standard JavaScript globals.
`debug` Add debug prefix and suffix.
`domprops` Mangle property names that overlaps
with DOM properties.
`keep_quoted` Only mangle unquoted properties.
`regex` Only mangle matched property names.
`reserved` List of names that should not be mangled.
-b, --beautify [options] Beautify output/specify output options:
`beautify` Enabled with `--beautify` by default.
`preamble` Preamble to prepend to the output. You
can use this to insert a comment, for
example for licensing information.
This will not be parsed, but the source
map will adjust for its presence.
`quote_style` Quote style:
0 - auto
1 - single
2 - double
3 - original
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
want to disable `negate_iife` under
compressor options.
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
`spidermonkey` to write UglifyJS or SpiderMonkey AST
as JSON to STDOUT respectively.
--comments [filter] Preserve copyright comments in the output. By
default this works like Google Closure, keeping
JSDoc-style comments that contain "@license" or
"@preserve". You can optionally pass one of the
following arguments to this flag:
- "all" to keep all comments
- a valid JS RegExp like `/foo/` or `/^!/` to
keep only matching comments.
Note that currently not *all* comments can be
kept when compression is on, because of dead
code removal or cascading statements into
sequences.
--config-file <file> Read `minify()` options from JSON file.
-d, --define <expr>[=value] Global definitions.
--ie8 Support non-standard Internet Explorer 8.
Equivalent to setting `ie8: true` in `minify()`
for `compress`, `mangle` and `output` options.
By default UglifyJS will not try to be IE-proof.
--keep-fnames Do not mangle/drop function names. Useful for
code relying on Function.prototype.name.
--name-cache <file> File to hold mangled name mappings.
--self Build UglifyJS as a library (implies --wrap UglifyJS)
--source-map [options] Enable source map/specify source map options:
`base` Path to compute relative paths from input files.
`content` Input source map, useful if you're compressing
JS that was generated from some other original
code. Specify "inline" if the source map is
included within the sources.
`filename` Name and/or location of the output source.
`includeSources` Pass this flag if you want to include
the content of source files in the
source map as sourcesContent property.
`root` Path to the original source to be included in
the source map.
`url` If specified, path to the source map to append in
`//# sourceMappingURL`.
--timings Display operations run time on STDERR.
--toplevel Compress and/or mangle variables in top level scope.
--verbose Print diagnostic messages.
--warn Print warning messages.
--wrap <name> Embed everything in a big function, making the
“exports” and “global” variables available. You
need to pass an argument to this option to
specify the name that your module will take
when included in, say, a browser.
Especifique --output
( -o
) para declarar el archivo de salida, de lo contrario, la salida va a STDOUT.
Opciones de mapa de origen CLI
UglifyJS puede generar un archivo de mapa de origen, que es muy útil para depurar su JavaScript comprimido. Para obtener un mapa de origen, pase
--source-map --output output.js
(el mapa de origen se escribirá en
output.js.map
).
Opciones adicionales:
--source-map "filename='<NAME>'"
para especificar el nombre del mapa de origen.--source-map "root='<URL>'"
para pasar la URL donde se pueden encontrar los archivos originales.--source-map "url='<URL>'"
para especificar la URL donde se puede encontrar el mapa de origen. De lo contrario, UglifyJS asume queX-SourceMap
se está utilizando HTTP y omitirá la//# sourceMappingURL=
directiva.
Por ejemplo:
1
2
3uglifyjs js/file1.js js/file2.js \
-o foo.min.js -c -m \
--source-map "root='http://foo.com/src',url='foo.min.js.map'"
Lo anterior comprimirá y destruirá file1.js
y file2.js
colocará la salida foo.min.js
y el mapa de origen foo.min.js.map
. El mapa de origen se referirá a http://foo.com/src/js/file1.js
y
http://foo.com/src/js/file2.js
(de hecho, aparecerá http://foo.com/src
como la raíz del mapa de origen y los archivos originales como js/file1.js
y
js/file2.js
).
Composed source map
Cuando está comprimiendo código JS generado por un compilador como CoffeeScript, la asignación al código JS no será demasiado útil. En su lugar, le gustaría volver a asignar el código original (es decir, CoffeeScript). UglifyJS tiene una opción para tomar un mapa de fuente de entrada. Asumiendo que tiene un mapeo de CoffeeScript → JS compilado, UglifyJS puede generar un mapa de CoffeeScript → JS comprimido mapeando cada token en el JS compilado a su ubicación original.
Para utilizar esta característica pase --source-map "content='/path/to/input/source.map'"
o --source-map "content=inline"
si el mapa fuente está incluido en línea con las fuentes.
Opciones de compresión CLI
Necesita pasar --compress
( -c
) para habilitar el compresor. Opcionalmente, puede pasar una lista separada por comas de opciones de compresión .
Las opciones están en la forma foo=bar
, o simplemente foo
(la última implica una opción booleana que desea establecer true
; es efectivamente un atajo para foo=true
).
Ejemplo:
1uglifyjs file.js -c toplevel,sequences=false
Opciones de manipulación CLI
Para habilitar el manipulador, debe pasar --mangle
( -m
). Se admiten las siguientes opciones (separadas por comas):
toplevel
(predeterminadofalse
): modifica los nombres declarados en el ámbito de nivel superior.eval
(predeterminadofalse
): modifica los nombres visibles en los ámbitos en los que se utilizaneval
owith
.
Cuando la alteración está habilitada pero desea evitar que se alteren ciertos nombres, puede declarar esos nombres con --mangle reserved
: pasar una lista de nombres separados por comas. Por ejemplo:
1uglifyjs ... -m reserved=['$','require','exports']
para evitar que se cambien los nombres require
, exports
y $
.
CLI manipulando nombres de propiedad ( --mangle-props
)
Nota: ESTO PROBABLEMENTE ROMPERÁ SU CÓDIGO. La modificación de los nombres de las propiedades es un paso independiente, diferente de la modificación del nombre de las variables. Páselo
--mangle-props
para habilitarlo. Modificará todas las propiedades en el código de entrada con la excepción de las propiedades DOM integradas y las propiedades en el núcleo de JavaScript. clases. Por ejemplo:
1
2
3
4
5
6
7
8
9
10
11// example.js
var x = {
baz_: 0,
foo_: 1,
calc: function() {
return this.foo_ + this.baz_;
}
};
x.bar_ = 2;
x["baz_"] = 3;
console.log(x.calc());
Mangle todas las propiedades (excepto JavaScript builtins
):
1$ uglifyjs example.js -c -m --mangle-props
1var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
Mangle todas las propiedades excepto las reserved
propiedades:
1$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
1var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
Mangle todas las propiedades que coincidan con regex
:
1$ uglifyjs example.js -c -m --mangle-props regex=/_$/
1var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
Combinando opciones de propiedades de mangle:
1$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
1var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
Para que esto sea de alguna utilidad, evitamos alterar los nombres estándar de JS de forma predeterminada ( --mangle-props builtins
para anular).
Se proporciona un archivo de exclusión predeterminado en el tools/domprops.json
que debería cubrir la mayoría de las propiedades estándar de JS y DOM definidas en varios navegadores. Pase
--mangle-props domprops
para deshabilitar esta función.
Se puede utilizar una expresión regular para definir qué nombres de propiedad deben modificarse. Por ejemplo, --mangle-props regex=/^_/
solo modificará los nombres de propiedad que comiencen con un guión bajo.
Cuando comprime varios archivos utilizando esta opción, para que funcionen juntos al final, debemos asegurarnos de que una propiedad se destruya con el mismo nombre en todos ellos. Para esto, pass --name-cache filename.json
y UglifyJS mantendrán estas asignaciones en un archivo que luego se puede reutilizar. Inicialmente debe estar vacío. Ejemplo:
1
2
3$ rm -f /tmp/cache.json # start fresh
$ uglifyjs file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js
$ uglifyjs file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js
Ahora, part1.js
y part2.js
serán coherentes entre sí en términos de nombres de propiedades destrozados.
No es necesario usar el caché de nombres si comprime todos sus archivos en una sola llamada a UglifyJS.
Modificar nombres sin comillas ( --mangle-props keep_quoted
)
El uso de nombre de propiedad entre comillas ( o["foo"]
) reserva el nombre de propiedad ( foo
) para que no se altere en todo el script, incluso cuando se usa en un estilo sin comillas ( o.foo
). Ejemplo:
1
2
3
4
5
6
7// stuff.js
var o = {
"foo": 1,
bar: 3
};
o.foo += o.bar;
console.log(o.foo);
1$ uglifyjs stuff.js --mangle-props keep_quoted -c -m
1var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
Debugging property name mangling
También puede pasar --mangle-props debug
para alterar los nombres de las propiedades sin oscurecerlos por completo. Por ejemplo, la propiedad o.foo
se alteraría o._$foo$_
con esta opción. Esto permite alterar las propiedades de una base de código grande y, al mismo tiempo, poder depurar el código e identificar dónde está alterando las cosas.
1$ uglifyjs stuff.js --mangle-props debug -c -m
1var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
También puede pasar un sufijo personalizado usando --mangle-props debug=XYZ
. Esto luego se alteraría o.foo
a o._$foo$XYZ_
. Puede cambiar esto cada vez que compile un script para identificar cómo se destruyó una propiedad. Una técnica es pasar un número aleatorio en cada compilación para simular el cambio de alteración con diferentes entradas (por ejemplo, cuando actualiza el script de entrada con nuevas propiedades) y para ayudar a identificar errores como escribir claves dañadas en el almacenamiento.
Referencia de API
Suponiendo la instalación a través de NPM, puede cargar UglifyJS en su aplicación de esta manera:
1var UglifyJS = require("uglify-js");
Existe una única función de alto nivel minify(code, options)
, que realizará todas las fases de minificación de forma configurable. Por defecto minify()
habilitará las opciones compress
y mangle
. Ejemplo:
1
2
3
4var code = "function add(first, second) { return first + second; }";
var result = UglifyJS.minify(code);
console.log(result.error); // runtime error, or `undefined` if no error
console.log(result.code); // minified output: function add(n,d){return n+d}
Puede minify
más de un archivo JavaScript a la vez utilizando un objeto para el primer argumento donde las claves son nombres de archivo y los valores son código fuente:
1
2
3
4
5
6
7var code = {
"file1.js": "function add(first, second) { return first + second; }",
"file2.js": "console.log(add(1 + 2, 3 + 4));"
};
var result = UglifyJS.minify(code);
console.log(result.code);
// function add(d,n){return d+n}console.log(add(3,7));
La toplevel
opcion:
1
2
3
4
5
6
7
8var code = {
"file1.js": "function add(first, second) { return first + second; }",
"file2.js": "console.log(add(1 + 2, 3 + 4));"
};
var options = { toplevel: true };
var result = UglifyJS.minify(code, options);
console.log(result.code);
// console.log(3+7);
La nameCache
opcion:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var options = {
mangle: {
toplevel: true,
},
nameCache: {}
};
var result1 = UglifyJS.minify({
"file1.js": "function add(first, second) { return first + second; }"
}, options);
var result2 = UglifyJS.minify({
"file2.js": "console.log(add(1 + 2, 3 + 4));"
}, options);
console.log(result1.code);
// function n(n,r){return n+r}
console.log(result2.code);
// console.log(n(3,7));
Puede conservar el caché de nombres en el sistema de archivos de la siguiente manera:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var cacheFileName = "/tmp/cache.json";
var options = {
mangle: {
properties: true,
},
nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
};
fs.writeFileSync("part1.js", UglifyJS.minify({
"file1.js": fs.readFileSync("file1.js", "utf8"),
"file2.js": fs.readFileSync("file2.js", "utf8")
}, options).code, "utf8");
fs.writeFileSync("part2.js", UglifyJS.minify({
"file3.js": fs.readFileSync("file3.js", "utf8"),
"file4.js": fs.readFileSync("file4.js", "utf8")
}, options).code, "utf8");
fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
Un ejemplo de una combinación de minify()
opciones:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21var code = {
"file1.js": "function add(first, second) { return first + second; }",
"file2.js": "console.log(add(1 + 2, 3 + 4));"
};
var options = {
toplevel: true,
compress: {
global_defs: {
"@console.log": "alert"
},
passes: 2
},
output: {
beautify: false,
preamble: "/* uglified */"
}
};
var result = UglifyJS.minify(code, options);
console.log(result.code);
// /* uglified */
// alert(10);"
Para producir advertencias:
1
2
3
4
5
6var code = "function f(){ var u; return 2 + 3; }";
var options = { warnings: true };
var result = UglifyJS.minify(code, options);
console.log(result.error); // runtime error, `undefined` in this case
console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ]
console.log(result.code); // function f(){return 5}
Un ejemplo de error:
1
2
3var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"});
console.log(JSON.stringify(result.error));
// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
Nota: a diferencia de `uglify-js@2.x, the
3.x`, la API no arroja errores. Para lograr un efecto similar, uno podría hacer lo siguiente:
1
2var result = UglifyJS.minify(code, options);
if (result.error) throw result.error;
Minificar opciones
warnings
(predeterminadofalse
): pasartrue
para devolver las advertencias del compresorresult.warnings
. Utilice el valor"verbose"
para obtener advertencias más detalladas.parse
(predeterminado{}
): pase un objeto si desea especificar algunas opciones de análisis adicionales .compress
(predeterminado{}
): pasefalse
para omitir la compresión por completo. Pase un objeto para especificar opciones de compresión personalizadas .mangle
(predeterminadotrue
): pasefalse
para omitir la alteración de nombres, o pase un objeto para especificar las opciones de alteración (ver más abajo).mangle.properties
(predeterminadofalse
): una subcategoría de la opción de mangle. Pase un objeto para especificar opciones de propiedad de mangle personalizadas .
output
(predeterminadonull
): pase un objeto si desea especificar opciones de salida adicionales . Los valores predeterminados están optimizados para una mejor compresión.sourceMap
(predeterminadofalse
): pase un objeto si desea especificar las opciones del mapa de origen .toplevel
(predeterminadofalse
) -configure entrue
si desea habilitar la modificación de nombre de función y variable de nivel superior y eliminar las variables y funciones no utilizadas.nameCache
(predeterminadonull
): pase un objeto vacío{}
o unnameCache
objeto usado anteriormente si desea almacenar en caché los nombres de variable y propiedad alterados a través de múltiples invocaciones deminify()
. Nota: esta es una propiedad de lectura / escritura.minify()
Leerá el estado de la caché de nombres de este objeto y lo actualizará durante la minificación para que el usuario pueda reutilizarlo o conservarlo externamente.ie8
(predeterminadofalse
) -configurado entrue
para admitir IE8.keep_fnames
(predeterminadofalse
:) -passtrue
para evitar descartar o alterar los nombres de las funciones. Útil para el código que se basa enFunction.prototype.name
.
Minimizar la estructura de opciones
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25{
parse: {
// parse options
},
compress: {
// compress options
},
mangle: {
// mangle options
properties: {
// mangle property options
}
},
output: {
// output options
},
sourceMap: {
// source map options
},
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}
Source map options
Para generar un mapa fuente:
1
2
3
4
5
6
7
8var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
sourceMap: {
filename: "out.js",
url: "out.js.map"
}
});
console.log(result.code); // minified output
console.log(result.map); // source map
Tenga en cuenta que el mapa de origen no se guarda en un archivo, es sólo regresó en
result.map
. El valor pasó para sourceMap.url
solamente se utiliza para establecer
//# sourceMappingURL=out.js.map
en result.code
. El valor de
filename
solamente se utiliza para establecer file
el atributo (ver la especificación ) en el archivo de mapa de origen.
Puede establecer que la opción sourceMap.url
sea "inline"
y el mapa fuente se adjuntará al código.
También puede especificar la propiedad sourceRoot para que se incluya en el mapa de origen:
1
2
3
4
5
6var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {
sourceMap: {
root: "http://example.com/src",
url: "out.js.map"
}
});
Si está comprimiendo JavaScript compilado y tiene un mapa fuente para ello, puede usar sourceMap.content
:
1
2
3
4
5
6
7var result = UglifyJS.minify({"compiled.js": "compiled code"}, {
sourceMap: {
content: "content from compiled.js.map",
url: "minified.js.map"
}
});
// same as before, it returns `code` and `map`
Si está utilizando el X-SourceMap
encabezado en su lugar, puede omitir sourceMap.url
.
Opciones de análisis
bare_returns
(predeterminadofalse
): admitereturn
declaraciones de nivel superiorhtml5_comments
(por defectotrue
)shebang
(predeterminadotrue
): soporte#!command
como primera línea
Comprimir opciones
arguments
(predeterminado :)true
: reempláceloarguments[index]
con el nombre del parámetro de función siempre que sea posible.booleans
(predeterminadotrue
:): varias optimizaciones para el contexto booleano, por ejemplo!!a ? b : c → a ? b : c
collapse_vars
(predeterminadotrue
:): contraiga las variables no constantes de un solo uso, si los efectos secundarios lo permiten.comparisons
(predeterminadotrue
:): aplica ciertas optimizaciones a los nodos binarios, p!(a <= b) → a > b
. ej. , intentos de negar nodos binarios, pa = !b && !c && !d && !e → a=!(b||c||d||e)
. ej., etc.conditionals
(predeterminadotrue
:): aplica optimizaciones paraif
-s y expresiones condicionalesdead_code
(predeterminadotrue
:) - eliminar el código inalcanzabledrop_console
(predeterminado :)false
- Pasetrue
para descartar llamadas aconsole.*
funciones. Si desea eliminar una llamada a una función específica comoconsole.info
y / o retener efectos secundarios de los argumentos de la función después de eliminar la llamada a la función, utilicepure_funcs
en su lugar.drop_debugger
(predeterminado :)true
- eliminardebugger;
declaracionesevaluate
(predeterminadotrue
:): intenta evaluar expresiones constantesexpression
(predeterminado :)false
- Pasetrue
para conservar los valores de finalización de las declaraciones de terminal sinreturn
, por ejemplo, en bookmarklets.global_defs
(predeterminado :){}
- ver compilación condicionalhoist_funs
(predeterminadofalse
:) - declaraciones de función de elevaciónhoist_props
(predeterminadotrue
:): eleva propiedades de objetos constantes y literales de matriz en variables regulares sujetas a un conjunto de restricciones. Por ejemplo:var o={p:1, q:2}; f(o.p, o.q);
se convierte af(1, 2);
. Nota:hoist_props
funciona mejor conmangle
habilitado, lacompress
opciónpasses
establecida en2
o superior y lacompress
opcióntoplevel
habilitada.hoist_vars
(predeterminadofalse
:) -var
declaraciones de elevación (esto esfalse
por defecto porque parece aumentar el tamaño de la salida en general)if_return
(predeterminadotrue
:) - optimizaciones para if / return y if / continueinline
(predeterminadotrue
:) - llamadas en línea para funcionar con unareturn
declaración / simple :false
- igual que0
0
- alineación para discapacitados1
- funciones simples en línea2
- funciones en línea con argumentos3
- funciones en línea con argumentos y variablestrue
- igual que3
join_vars
(predeterminadotrue
:) - unirse avar
declaraciones consecutivaskeep_fargs
(predeterminadotrue
:) - Evita que el compresor descarte argumentos de función no utilizados. Necesita esto para el código que se basa enFunction.length
.keep_fnames
(predeterminado :)false
- Aprobadotrue
para evitar que el compresor descarte los nombres de las funciones. Útil para el código que se basaFunction.prototype.name
. Consulte también: lakeep_fnames
opción mangle .keep_infinity
(predeterminado :)false
- Pasetrue
para evitar queInfinity
se comprima1/0
, lo que puede causar problemas de rendimiento en Chrome.loops
(por defectotrue
:) - optimizaciones parado
,while
yfor
bucles cuando podemos determinar la condición estática.negate_iife
(predeterminadotrue
:) - niega las "Expresiones de funciones llamadas inmediatamente" donde se descarta el valor de retorno, para evitar los parens que insertaría el generador de código.passes
(predeterminado :)1
: el número máximo de veces que se puede ejecutar compress. En algunos casos, más de una pasada conduce a un código más comprimido. Tenga en cuenta que más pasadas tomarán más tiempo.properties
(predeterminadotrue
:) - reescribe el acceso a la propiedad usando la notación de puntos, por ejemplofoo["bar"] → foo.bar
pure_funcs
(predeterminado :)null
- Puede pasar una serie de nombres y UglifyJS asumirá que esas funciones no producen efectos secundarios. PELIGRO: no comprobará si el nombre está redefinido en el alcance. Un caso de ejemplo aquí, por ejemplovar q = Math.floor(a/b)
. Si la variableq
no es usado en otro lugar, UglifyJS lo eliminará, pero aún lo mantendráMath.floor(a/b)
, sin saber qué hace. Puede pasarpure_funcs: [ 'Math.floor' ]
para hacerle saber que esta función no producirá ningún efecto secundario, en cuyo caso se descartaría toda la declaración. la implementación agrega algo de sobrecarga (la compresión será más lenta). Asegúrese de que los símbolos debajopure_funcs
también estén debajomangle.reserved
para evitar alteraciones.pure_getters
(predeterminado :)"strict"
- Si pasatrue
por esto, UglifyJS asumirá que el acceso a la propiedad del objeto (por ejemplo,foo.bar
ofoo["bar"]
) no tiene ningún efecto secundario. Especifique"strict"
tratarfoo.bar
como libre de efectos secundarios solo cuandofoo
esté seguro de no lanzar, es decir, nonull
oundefined
.reduce_funcs
(predeterminadotrue
:): permite que las funciones de un solo uso se incluyan como expresiones de función cuando sea posible, lo que permite una mayor optimización. Habilitada de forma predeterminada. La opción depende de quereduce_vars
esté habilitada. Algunos códigos se ejecutan más rápido en el motor Chrome V8 si esta opción está inhabilitada. No lo hace de forma negativa afectar a otros navegadores importantes.reduce_vars
(predeterminadotrue
:): mejora la optimización de las variables asignadas y utilizadas como valores constantes.sequences
(predeterminadotrue
:): une declaraciones simples consecutivas utilizando el operador de coma. Puede establecerse en un entero positivo para especificar el número máximo de secuencias de coma consecutivas que se generarán. Si esta opción se establece entrue
, elsequences
límite predeterminado es200
. Establecer opción enfalse
o0
para deshabilitar. Lasequences
longitud más pequeña es2
. Unsequences
valor de1
tiene derechos adquiridos para ser equivalente atrue
y como tal significa200
. En raras ocasiones, el límite de secuencias predeterminado conduce a tiempos de compresión muy lentos, en cuyo caso20
se recomienda un valor de o menos.side_effects
(predeterminado :)true
- Pasefalse
para deshabilitar las funciones potencialmente descartadas marcadas como "puras". Una llamada de función se marca como "pura" si una anotación de comentario/*@__PURE__*/
o/*#__PURE__*/
inmediatamente precede a la llamada. Por ejemplo:/*@__PURE__*/foo();
switches
(predeterminadotrue
:) - eliminar duplicados y eliminarswitch
ramas inalcanzablestoplevel
(predeterminadofalse
:): elimina funciones ("funcs"
) y / o variables ("vars"
) no referenciadas en el ámbito de nivel superior (false
de forma predeterminada,true
para eliminar las funciones y variables no referenciadas)top_retain
(predeterminadonull
:): evita que se eliminen determinadas funciones y variables de nivelunused
superior (puede ser una matriz, una coma separada, una expresión regular o una función. Implicatoplevel
)typeofs
(predeterminado :)true
: se transformatypeof foo == "undefined"
enfoo === void 0
. Nota: se recomienda establecer este valor enfalse
para IE10 y versiones anteriores debido a problemas conocidos.unsafe
(predeterminadofalse
:) - aplicar transformaciones "inseguras" (discusión a continuación)unsafe_comps
(predeterminado :)false
- comprime expresiones comoa <= b
asumiendo que ninguno de los operandos puede ser (forzado a)NaN
.unsafe_Function
(predeterminadofalse
:) - comprime y mangleFunction(args, code)
cuando ambosargs
ycode
son cadenas literales.unsafe_math
(predeterminadofalse
:): optimiza expresiones numéricas como2 * x * 3
en6 * x
, lo que puede dar resultados de coma flotante imprecisos.unsafe_proto
(predeterminadofalse
:) - optimizar expresiones comoArray.prototype.slice.call(a)
en[].slice.call(a)
unsafe_regexp
(predeterminadofalse
:): habilita las sustituciones de variables conRegExp
valores de la misma manera que si fueran constantes.unsafe_undefined
(predeterminadofalse
:): sustitúyalovoid 0
si hay una variable nombradaundefined
en el alcance (el nombre de la variable se alterará, por lo general se reducirá a un solo carácter)unused
(predeterminadotrue
:): elimina funciones y variables no referenciadas (las asignaciones de variables directas simples no cuentan como referencias a menos que se establezcan en"keep_assign"
)warnings
(predeterminadofalse
:): muestra advertencias al dejar caer un código inalcanzable o declaraciones no utilizadas, etc.
Opciones de Mangle
eval
(predeterminadofalse
): pasetrue
para modificar los nombres visibles en los ámbitos en los que se utilizaneval
owith
.keep_fnames
(predeterminadofalse
) - Pasartrue
para no alterar los nombres de las funciones. Útil para el código que se basaFunction.prototype.name
. Consulte también: lakeep_fnames
opción de compresión .reserved
(predeterminado[]
) - Pase AN BE Should Array de identificadores de los que se excluye la manipulación Ejemplo :["foo", "bar"]
..toplevel
(predeterminadofalse
): pasatrue
para modificar los nombres declarados en el ámbito de nivel superior.
Ejemplos:
1
2
3
4
5// test.js
var globalVar;
function funcName(firstLongName, anotherLongName) {
var myVariable = firstLongName + anotherLongName;
}
1
2
3
4
5
6
7
8
9
10var code = fs.readFileSync("test.js", "utf8");
UglifyJS.minify(code).code;
// 'function funcName(a,n){}var globalVar;'
UglifyJS.minify(code, { mangle: { reserved: ['firstLongName'] } }).code;
// 'function funcName(firstLongName,a){}var globalVar;'
UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
// 'function n(n,a){}var a;'
Mangle properties options
builtins
(predeterminado :)false
: se utilizatrue
para permitir la modificación de las propiedades DOM integradas. No se recomienda anular esta configuración.debug
(predeterminadofalse
:) -— Mangle nombres con el nombre original todavía presente. Pase una cadena vacía""
para habilitar, o una cadena no vacía para establecer el sufijo de depuración.keep_quoted
(predeterminadofalse
:) -— Mangle sólo nombres de propiedad sin comillas.regex
(predeterminadonull
:) -— Pasa un literal RegExp para modificar únicamente los nombres de propiedad que coincidan con la expresión regular.reserved
(predeterminado[]
:) - No altere los nombres de propiedad que aparecen en lareserved
matriz.
Opciones de salida
El generador de código intenta generar el código más corto posible de forma predeterminada. En caso de que desee una salida embellecida, pase --beautify
( -b
). Opcionalmente, puede pasar argumentos adicionales que controlen la salida del código:
ascii_only
(predeterminadofalse
): escape de caracteres Unicode en cadenas y expresiones regulares (afecta a las directivas con caracteres no ascii que no son válidos)beautify
(predeterminadotrue
): si realmente se embellecerá la salida. Pasar-b
establecerá esto en verdadero, pero es posible que deba pasar-b
incluso cuando desee generar código minificado, para especificar argumentos adicionales, de modo que pueda usarlo-b beautify=false
para anularlo.braces
(por defectofalse
) - Siempre en insertar llavesif
,for
,do
,while
owith
declaraciones, el incluso su cuerpo es la declaración UN SOLO SI.comments
(predeterminadofalse
): pasatrue
o"all"
para preservar todos los comentarios,"some"
para preservar algunos comentarios, una cadena de expresión regular (p/^!/
. ej. ) o una función.indent_level
(por defecto4
)indent_start
(predeterminado0
) - prefija todas las líneas con esa cantidad de espaciosinline_script
(predeterminadotrue
): escape de los comentarios HTML y la barra inclinada en las ocurrencias de</script>
en cadenaskeep_quoted_props
(predeterminadofalse
): cuando está activado, evita que se eliminen las comillas de los nombres de propiedad en los objetos literales.max_line_len
(predeterminadofalse
) - longitud máxima de línea (para código desactualizado)preamble
(predeterminadonull
): cuando se pasa, debe ser una cadena y se antepondrá literalmente a la salida. El mapa de origen se ajustará a este texto. Se puede usar para insertar un comentario que contenga información de licencia, por ejemplo.preserve_line
(predeterminadofalse
): pasetrue
para conservar las líneas, pero solo funciona sibeautify
está configurado enfalse
.quote_keys
(predeterminadofalse
): pasetrue
para citar todas las claves en objetos literalesquote_style
(predeterminado0
): estilo de comillas preferido para cadenas (también afecta a las directivas y los nombres de propiedad entre comillas):0
- prefiere comillas dobles, cambia a comillas simples cuando hay más comillas dobles en la propia0
cadena.Es mejor para el tamaño de gzip.1
- utilice siempre comillas simples2
- siempre use comillas dobles3
- utilice siempre las citas originales
semicolons
(por defectotrue
) - declaraciones separadas con punto y coma. Si pasa,false
entonces siempre que sea posible usaremos una nueva línea en lugar de un punto y coma, lo que conducirá a una salida más legible de código uglified (el tamaño antes de gzip podría ser más pequeño; el tamaño después de gzip podría ser insignificantemente más grande).shebang
(predeterminadotrue
): conserva shebang#!
en el preámbulo (scripts bash)webkit
(predeterminadofalse
): habilita soluciones alternativas para los errores de WebKit. Los usuarios de PhantomJS deben establecer esta opción entrue
.width
(predeterminado80
): solo tiene efecto cuando el embellecimiento está activado, esto especifica un ancho de línea (orientativo) que el embellecedor intentará obedecer. Se refiere al ancho del texto de la línea (excluyendo la sangría). Actualmente no funciona muy bien , pero hace que el código generado por UglifyJS sea más legible.wrap_iife
(predeterminadofalse
): pasetrue
para ajustar las expresiones de función invocadas inmediatamente. Consulte el n. ° 640 para obtener más detalles.
Diverso
Keeping copyright notices or other comments
Puede pasar --comments
para retener ciertos comentarios en la salida. De forma predeterminada, mantendrá los comentarios estilo JSDoc que contengan "@preserve", "@license" o "@cc_on" (compilación condicional para IE). Puede pasar
--comments all
para mantener todos los comentarios, o una expresión regular de JavaScript válida para mantener solo los comentarios que coincidan con esta expresión regular. Por ejemplo --comments /^!/
, mantendrá los comentarios como /*! Copyright Notice */
.
Sin embargo, tenga en cuenta que puede haber situaciones en las que se pierdan los comentarios. Por ejemplo:
1
2
3
4
5
6
7function f() {
/** @preserve Foo Bar */
function g() {
// this function is never called
}
return something();
}
Aunque tiene "@preserve", el comentario se perderá porque g
el compresor descarta la función interna (que es el nodo AST al que se adjunta el comentario) como no referenciada.
Los comentarios más seguros donde colocar la información de derechos de autor (u otra información que debe mantenerse en la salida) son los comentarios adjuntos a los nodos de nivel superior.
La unsafe
compress
opcion
Permite algunas transformaciones que pueden romper la lógica del código en ciertos casos artificiales, pero debería funcionar bien para la mayoría del código. Es posible que desee probarlo en su propio código, debería reducir el tamaño reducido. Esto es lo que sucede cuando esta marca está activada:
new Array(1, 2, 3)
oArray(1, 2, 3)
→[ 1, 2, 3 ]
new Object()
→{}
String(exp)
oexp.toString()
→"" + exp
new Object/RegExp/Function/Error/Array (...)
→ descartamos elnew
Conditional compilation
Puede usar el modificador --define
( -d
) para declarar variables globales que UglifyJS asumirá que son constantes (a menos que estén definidas en el alcance). Por ejemplo, si pasa --define DEBUG=false
entonces, junto con la eliminación del código muerto, UglifyJS descartará lo siguiente de la salida:
1
2
3if (DEBUG) {
console.log("debug stuff");
}
Puede especificar constantes anidadas en forma de --define env.DEBUG=false
.
UglifyJS advertirá sobre la condición siempre falsa y sobre la eliminación de código inalcanzable; por ahora no hay opción para desactivar solo esta advertencia específica, puede pasar warnings=false
para desactivar todas las advertencias.
Otra forma de hacerlo es declarar sus globales como constantes en un archivo separado e incluirlo en la compilación. Por ejemplo, puede tener un
build/defines.js
archivo con lo siguiente:
1
2
3var DEBUG = false;
var PRODUCTION = true;
// etc.
y construye tu código así:
1uglifyjs build/defines.js js/foo.js js/bar.js... -c
UglifyJS notará las constantes y, dado que no se pueden alterar, evaluará las referencias a ellas al valor en sí y eliminará el código inalcanzable como de costumbre. La compilación contendrá las const
declaraciones si las usa. Si está apuntando a entornos <ES6 que no no es compatible const
, usar var
con reduce_vars
(habilitado de forma predeterminada) debería ser suficiente.
Conditional compilation API
También puede usar la compilación condicional a través de la API programática. Con la diferencia de que el nombre de la propiedad es global_defs
y es una propiedad del compresor:
1
2
3
4
5
6
7
8var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
compress: {
dead_code: true,
global_defs: {
DEBUG: false
}
}
});
Para reemplazar un identificador con una expresión arbitraria no constante, es necesario prefijar la global_defs
clave con "@"
para indicarle a UglifyJS que analice el valor como una expresión:
1
2
3
4
5
6
7
8UglifyJS.minify("alert('hello');", {
compress: {
global_defs: {
"@alert": "console.log"
}
}
}).code;
// returns: 'console.log("hello");'
De lo contrario, sería reemplazado como literal de cadena:
1
2
3
4
5
6
7
8UglifyJS.minify("alert('hello');", {
compress: {
global_defs: {
"alert": "console.log"
}
}
}).code;
// returns: '"console.log"("hello");'
Usando Uglify AST nativo con minify()
1
2
3
4
5
6
7
8
9
10
11
12
13// example: parse only, produce native Uglify AST
var result = UglifyJS.minify(code, {
parse: {},
compress: false,
mangle: false,
output: {
ast: true,
code: false // optional - faster if false
}
});
// result.ast contains native Uglify AST
1
2
3
4
5
6
7
8
9
10
11
12
13
14// example: accept native Uglify AST input and then compress and mangle
// to produce both code and native AST.
var result = UglifyJS.minify(ast, {
compress: {},
mangle: {},
output: {
ast: true,
code: true // optional - faster if false
}
});
// result.ast contains native Uglify AST
// result.code contains the minified code in string form.
Working with Uglify AST
La transversal y la transformación del AST nativo se pueden realizar mediante
TreeWalker
y
TreeTransformer
respectivamente.
ESTree / SpiderMonkey AST
UglifyJS tiene su propio formato de árbol de sintaxis abstracto; por razones prácticas, no podemos cambiar fácilmente al uso interno del SpiderMonkey AST.Sin embargo, UglifyJS ahora tiene un convertidor que puede importar un SpiderMonkey AST.
Por ejemplo, Acorn es un analizador súper rápido que produce un SpiderMonkey AST. Tiene una pequeña utilidad CLI que analiza un archivo y vuelca el AST en JSON en la salida estándar. Para usar UglifyJS para manipular y comprimir eso:
1acorn file.js | uglifyjs -p spidermonkey -m -c
La -p spidermonkey
opción le dice a UglifyJS que todos los archivos de entrada no son JavaScript, sino código JS descrito en SpiderMonkey AST en JSON. Por lo tanto, no usamos nuestro propio analizador en este caso, solo transformamos ese AST en nuestro AST interno.
Use Acorn for parsing
Más por diversión, agregué la -p acorn
opción que usará Acorn para hacer todo el análisis. Si pasa esta opción, UglifyJS lo hará require("acorn")
.
Acorn es realmente rápido (por ejemplo, 250ms en lugar de 380ms en un código de 650K), pero convertir el árbol SpiderMonkey que Acorn produce toma otros 150ms, por lo que en total es un poco más que usar el analizador de UglifyJS.
Uglify Fast Minify Mode
No es bien conocida, pero los espacios en blanco de eliminación y Symbol mangling representa el 95% de al La reducción de tamaño en el código minified MOST JavaScript -. Código no Elaborar las transformaciones simplemente se puede desactivar compress
para acelerar afear se basa en un 3 a 4 veces An en el este es el modo RÁPIDO. mangle
Uglify tiene velocidades de minificación y tamaños de gzip comparables a
butternut
:
d3.js | minimizar el tamaño | tamaño gzip | minificar el tiempo (segundos) |
---|---|---|---|
original | 451,131 | 108,733 | - |
uglify-js@3.0.24 mangle = false, compress = false | 316.600 | 85,245 | 0,70 |
uglify-js@3.0.24 mangle = true, compress = false | 220,216 | 72,730 | 1,13 |
butternut@0.4.6 | 217,568 | 72,738 | 1,41 |
uglify-js@3.0.24 mangle = true, compress = true | 212,511 | 71.560 | 3.36 |
babili@0.1.4 | 210,713 | 72,140 | 12,64 |
Para habilitar el modo de minificación rápida desde la CLI, use:
1uglifyjs file.js -m
Para habilitar el modo de minificación rápida con el uso de la API:
1UglifyJS.minify(code, { compress: false, mangle: true });
Mapas de origen y depuración
Se compress
sabe que varias transformaciones que simplifican, reorganizan, incorporan y eliminan el código tienen un efecto adverso en la depuración con mapas fuente. Esto se espera ya que el código está optimizado y las asignaciones a menudo simplemente no son posibles debido a que parte del código ya no existe. Para una mayor fidelidad en la fuente La depuración de mapas deshabilita la compress
opción Uglify y solo usa mangle
.
Compiler assumptions
Para permitir mejores optimizaciones, el compilador hace varias suposiciones:
.toString()
y.valueOf()
no tienen efectos secundarios, y para los objetos integrados no se han anulado.undefined
,NaN
YInfinity
no se han redefinido externamente.arguments.callee
,arguments.caller
YFunction.prototype.caller
no se utilizan.- El código no espera que el contenido de
Function.prototype.toString()
niError.prototype.stack
sea nada en particular. - Obtener y configurar propiedades en un objeto simple no causa otros efectos secundarios (usar
.watch()
oProxy
). - Pueden añadirse el objeto Properties, eliminado y Modificado (no impedido con
Object.defineProperty()
,Object.defineProperties()
,Object.freeze()
,Object.preventExtensions()
oObject.seal()
).