UglifyJS 3
UglifyJS est une boîte à outils d'analyseur, de minificateur, de compresseur et d'embellisseur JavaScript.
Note:
uglify-js@3
possède une API et une CLI simplifiées qui ne sont pas rétrocompatibles avecuglify-js@2
.- La documentation pour
2.x
les versions d'UglifyJS peut être trouvée ici . uglify-js
ne prend en charge que JavaScript (ECMAScript 5).- Pour réduire ECMAScript 2015 ou supérieur, transpilez à l'aide d'outils comme Babel .
Installer
Assurez-vous d'abord d'avoir installé la dernière version de node.js (vous devrez peut-être redémarrer votre ordinateur après cette étape).
Depuis NPM pour une utilisation comme application en ligne de commande :
1npm install uglify-js -g
Depuis NPM pour une utilisation programmatique :
1npm install uglify-js
Utilisation de la ligne de commande
1uglifyjs [input files] [options]
UglifyJS peut prendre plusieurs fichiers d'entrée. Il est recommandé de transmettre d'abord les fichiers d'entrée, puis de transmettre les options. UglifyJS analysera les fichiers d'entrée dans l'ordre et appliquera toutes les options de compression. Les fichiers sont analysés dans la même portée globale, c'est-à-dire une référence. d'un fichier à une variable/fonction déclarée dans un autre fichier correspondra correctement.
Si aucun fichier d'entrée n'est spécifié, UglifyJS lira depuis STDIN.
Si vous souhaitez passer vos options avant les fichiers d'entrée, séparez les deux par un double tiret pour éviter que les fichiers d'entrée ne soient utilisés comme arguments d'option :
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.
Spécifiez --output
( -o
) pour déclarer le fichier de sortie. Sinon, la sortie va vers STDOUT.
Options de mappage source CLI
UglifyJS peut générer un fichier de carte source, ce qui est très utile pour déboguer votre JavaScript compressé. Pour obtenir une carte source, transmettez
--source-map --output output.js
(la carte source sera écrite dans
output.js.map
).
Options additionelles:
--source-map "filename='<NAME>'"
pour spécifier le nom de la carte source.--source-map "root='<URL>'"
pour transmettre l'URL où les fichiers originaux peuvent être trouvés.--source-map "url='<URL>'"
pour spécifier l'URL où la carte source peut être trouvée. Sinon, UglifyJS suppose que HTTPX-SourceMap
est utilisé et omettra la//# sourceMappingURL=
directive.
Par exemple:
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'"
Ce qui précède compressera et modifiera file1.js
et file2.js
, déposera la sortie dans foo.min.js
et la carte source dans foo.min.js.map
. Le mappage source fera référence à http://foo.com/src/js/file1.js
et
http://foo.com/src/js/file2.js
(en fait, il sera répertorié http://foo.com/src
comme racine de la carte source et les fichiers originaux comme js/file1.js
et
js/file2.js
).
Composed source map
Lorsque vous compressez du code JS qui a été généré par un compilateur tel que CoffeeScript, le mappage vers le code JS ne sera pas très utile. Au lieu de cela, vous souhaitez revenir au code d'origine (c'est-à-dire CoffeeScript). UglifyJS a un option pour prendre une carte de source d'entrée. En supposant que vous ayez un mappage de CoffeeScript → JS compilé, UglifyJS peut générer une carte à partir de CoffeeScript → JS compressé en mappant chaque jeton du JS compilé à son emplacement d'origine.
Pour utiliser cette fonctionnalité, passez --source-map "content='/path/to/input/source.map'"
ou --source-map "content=inline"
si la carte source est incluse en ligne avec les sources.
Options de compression CLI
Vous devez transmettre --compress
(-c
) pour activer le compresseur. Vous pouvez éventuellement transmettre une liste d' options de compression séparées par des virgules .
Les options sont sous la forme foo=bar
, ou simplement foo
(ce dernier implique une option booléenne que vous souhaitez définir true
; c'est en fait un raccourci pour foo=true
).
Exemple:
1uglifyjs file.js -c toplevel,sequences=false
Options de modification CLI
Pour activer le mangler, vous devez passer --mangle
(-m
). Les options suivantes (séparées par des virgules) sont prises en charge :
toplevel
(par défautfalse
) -- noms mangle déclarés dans la portée de niveau supérieur.eval
(par défautfalse
) -- noms mangle visibles dans les étendues oùeval
ouwith
sont utilisés.
Lorsque la modification est activée mais que vous souhaitez empêcher la modification de certains noms, vous pouvez déclarer ces noms avec --mangle reserved
— transmettre une liste de noms séparés par des virgules. Par exemple :
1uglifyjs ... -m reserved=['$','require','exports']
pour empêcher que les noms require
, exports
et $
soient modifiés.
Noms de propriété de modification CLI ( --mangle-props
)
Remarque : CECI VA PROBABLEMENT CASSER VOTRE CODE. La modification des noms de propriétés est une étape distincte, différente de la modification des noms de variables. Passez
--mangle-props
pour l'activer. Cela modifiera toutes les propriétés du code d'entrée, à l'exception des propriétés intégrées au DOM et des propriétés du noyau JavaScript. cours. Par 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());
Mangle toutes les propriétés (sauf pour 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 toutes les propriétés à l'exception des reserved
propriétés :
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 toutes les propriétés correspondant à unregex
:
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());
Combinaison des options de propriétés 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());
Pour que cela soit utile, nous évitons de modifier les noms JS standard par défaut ( --mangle-props builtins
pour remplacer).
Un fichier d'exclusion par défaut est fourni et tools/domprops.json
devrait couvrir la plupart des propriétés JS et DOM standard définies dans divers navigateurs. Passez
--mangle-props domprops
pour désactiver cette fonctionnalité.
Une expression régulière peut être utilisée pour définir quels noms de propriétés doivent être modifiés. Par exemple, --mangle-props regex=/^_/
seuls les noms de propriétés commençant par un trait de soulignement seront modifiés.
Lorsque vous compressez plusieurs fichiers à l'aide de cette option, pour qu'ils fonctionnent ensemble à la fin, nous devons nous assurer d'une manière ou d'une autre qu'une propriété est mutilée sous le même nom dans chacun d'eux. Pour cela, passez --name-cache filename.json
et UglifyJS conservera ces mappages dans un fichier qui peut ensuite être réutilisé. Il doit être initialement vide. 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
Désormais, part1.js
ils part2.js
seront cohérents les uns avec les autres en termes de noms de propriétés mutilés.
L'utilisation du cache de noms n'est pas nécessaire si vous compressez tous vos fichiers en un seul appel à UglifyJS.
Mutilation des noms non cités ( --mangle-props keep_quoted
)
L'utilisation d'un nom de propriété entre guillemets ( o["foo"]
) réserve le nom de propriété ( foo
) afin qu'il ne soit pas mutilé tout au long du script, même lorsqu'il est utilisé dans un style sans guillemets ( 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
1var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
Debugging property name mangling
Vous pouvez également passer --mangle-props debug
afin de modifier les noms de propriétés sans les masquer complètement. Par exemple, la propriété o.foo
serait modifiée o._$foo$_
avec cette option. Cela permet de modifier les propriétés d'une grande base de code tout en étant capable de déboguer le code et d'identifier où la modification casse les choses.
1$ uglifyjs stuff.js --mangle-props debug -c -m
1var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
Vous pouvez également transmettre un suffixe personnalisé en utilisant --mangle-props debug=XYZ
. Cela sera ensuite modifié o.foo
en o._$foo$XYZ_
. Vous pouvez modifier cela chaque fois que vous compilez un script pour identifier comment une propriété a été modifiée. Une technique consiste à transmettre un nombre aléatoire à chaque compilation pour simuler une modification avec différents entrées (par exemple lorsque vous mettez à jour le script d'entrée avec de nouvelles propriétés) et pour aider à identifier des erreurs telles que l'écriture de clés mutilées dans le stockage.
Référence API
En supposant une installation via NPM, vous pouvez charger UglifyJS dans votre application comme ceci :
1var UglifyJS = require("uglify-js");
Il existe une seule fonction de haut niveau, minify(code, options)
, qui effectuera toutes les phases de minification de manière configurable. Par défaut, minify()
elle activera les options compress
et mangle
. Exemple :
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}
Vous pouvez créer minify
plusieurs fichiers JavaScript à la fois en utilisant un objet pour le premier argument où les clés sont des noms de fichiers et les valeurs sont le code source :
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));
L' toplevel
option:
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);
L' nameCache
option:
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));
Vous pouvez conserver le cache de noms dans le système de fichiers de la manière suivante :
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 exemple de combinaison d' minify()
options :
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);"
Pour produire des avertissements :
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 exemple d'erreur :
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}
Remarque : contrairement à uglify-js@2.x
, l' 3.x
API ne génère pas d'erreurs. Pour obtenir un effet similaire, vous pouvez procéder comme suit :
1
2var result = UglifyJS.minify(code, options);
if (result.error) throw result.error;
Réduire les options
warnings
(par défautfalse
) : transmettrue
pour renvoyer les avertissements du compresseur dansresult.warnings
. Utilisez la valeur"verbose"
pour des avertissements plus détaillés.parse
(par défaut{}
) — transmettez un objet si vous souhaitez spécifier des options d'analyse supplémentaires .compress
(par défaut{}
) — passerfalse
pour ignorer complètement la compression. Passer un objet pour spécifier des options de compression personnalisées .mangle
(par défauttrue
) — passefalse
pour ignorer la modification des noms, ou passe un objet pour spécifier les options de modification (voir ci-dessous).mangle.properties
(par défautfalse
) — une sous-catégorie de l'option mangle. Passez un objet pour spécifier les options de propriété mangle personnalisées .
output
(par défautnull
) — transmettez un objet si vous souhaitez spécifier des options de sortie supplémentaires . Les valeurs par défaut sont optimisées pour une meilleure compression.sourceMap
(par défautfalse
) - transmettez un objet si vous souhaitez spécifier les options de la carte source .toplevel
(par défautfalse
) - défini surtrue
si vous souhaitez activer la modification des variables et des noms de fonctions de niveau supérieur et supprimer les variables et fonctions inutilisées.nameCache
(par défautnull
) - transmettez un objet vide{}
ou unnameCache
objet précédemment utilisé si vous souhaitez mettre en cache les noms de variables et de propriétés mutilés lors de plusieurs invocations deminify()
. Remarque : il s'agit d'une propriété en lecture/écriture.minify()
lira l'état du cache de noms de cet objet et le mettra à jour pendant la minification afin qu'il puisse être réutilisé ou conservé en externe par l'utilisateur.ie8
(par défautfalse
) - configuré pourtrue
prendre en charge IE8.keep_fnames
(par défaut :false
) - passetrue
pour empêcher la suppression ou la modification des noms de fonctions. Utile pour le code reposant surFunction.prototype.name
.
Réduire la structure des 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{
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
Pour générer une carte source :
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
Notez que la carte source n'est pas enregistrée dans un fichier, elle est simplement renvoyée dans
result.map
. La valeur transmise sourceMap.url
est uniquement utilisée pour définir
//# sourceMappingURL=out.js.map
dans result.code
. La valeur de
filename
est uniquement utilisée pour définir file
l'attribut (voir la spécification ) dans le fichier de carte source.
Vous pouvez définir l'option sourceMap.url
sur be "inline"
et la carte source sera ajoutée au code.
Vous pouvez également spécifier la propriété sourceRoot à inclure dans le mappage source :
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 vous compressez du JavaScript compilé et disposez d'une carte source pour celui-ci, vous pouvez utilisersourceMap.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 vous utilisez l' X-SourceMap
en-tête à la place, vous pouvez simplement l'omettre sourceMap.url
.
Options d'analyse
bare_returns
(par défautfalse
) -- prend en chargereturn
les instructions de niveau supérieurhtml5_comments
(défauttrue
)shebang
(par défauttrue
) -- prise en charge#!command
comme première ligne
Options de compression
arguments
(par défaut :true
) -- remplacerarguments[index]
par le nom du paramètre de fonction chaque fois que possible.booleans
(par défaut :true
) -- diverses optimisations pour le contexte booléen, par exemple!!a ? b : c → a ? b : c
collapse_vars
(par défaut :true
) -- Réduire les variables non constantes à usage unique, si les effets secondaires le permettent.comparisons
(par défaut :true
) -- appliquer certaines optimisations aux nœuds binaires, par exemple!(a <= b) → a > b
, les tentatives d'annulation des nœuds binaires, par exemple,a = !b && !c && !d && !e → a=!(b||c||d||e)
etc.conditionals
(par défaut :true
) -- appliquer des optimisations pourif
-s et expressions conditionnellesdead_code
(par défaut :true
) -- supprime le code inaccessibledrop_console
(par défaut :false
) -- Passertrue
pour ignorer les appels auxconsole.*
fonctions. Si vous souhaitez supprimer un appel de fonction spécifique tel queconsole.info
et/ou conserver les effets secondaires des arguments de fonction après avoir abandonné l'appel de fonction, utilisez-lepure_funcs
à la place.drop_debugger
(par défaut :true
) -- supprimerdebugger;
les instructionsevaluate
(par défaut :true
) -- tentative d'évaluation d'expressions constantesexpression
(par défaut :false
) -- Passertrue
pour conserver les valeurs d'achèvement des instructions de terminal sansreturn
, par exemple dans les bookmarklets.global_defs
(par défaut :{}
) -- voir compilation conditionnellehoist_funs
(par défaut :false
) -- déclarations de fonction de levagehoist_props
(par défaut :true
) -- hisse les propriétés des littéraux d'objet et de tableau constants vers des variables régulières soumises à un ensemble de contraintes. Par exemple :var o={p:1, q:2}; f(o.p, o.q);
est converti enf(1, 2);
. Remarque :hoist_props
fonctionne mieux avecmangle
activé, l'compress
optionpasses
définie sur2
ou supérieure et l'compress
optiontoplevel
activée.hoist_vars
(par défaut :false
) --var
déclarations de levage (c'estfalse
par défaut car cela semble augmenter la taille de la sortie en général)if_return
(par défaut :true
) -- optimisations pour if/return et if/continueinline
(par défaut :true
) -- appels en ligne à la fonction avecreturn
l'instruction simple/ :false
--pareil que0
0
-- inlining désactivé1
-- fonctions simples en ligne2
-- fonctions en ligne avec arguments3
-- fonctions en ligne avec arguments et variablestrue
--pareil que3
join_vars
(par défaut :true
) -- joindrevar
des instructions consécutiveskeep_fargs
(par défaut :true
) -- Empêche le compresseur d'ignorer les arguments de fonction inutilisés. Vous en avez besoin pour le code qui repose surFunction.length
.keep_fnames
(par défaut :false
) -- Passetrue
pour empêcher le compresseur d'ignorer les noms de fonctions. Utile pour le code s'appuyant surFunction.prototype.name
. Voir aussi : l'keep_fnames
option mangle .keep_infinity
(par défaut :false
) -- Passertrue
pour éviterInfinity
d'être compressé dans1/0
, ce qui peut entraîner des problèmes de performances sur Chrome.loops
(par défaut :true
) -- optimisations pourdo
et boucles lorsquewhile
nousfor
pouvons déterminer statiquement la condition.negate_iife
(par défaut :true
) -- annule les "Expressions de fonction immédiatement appelées" où la valeur de retour est ignorée, pour éviter les parenthèses que le générateur de code insérerait.passes
(par défaut :1
) -- Le nombre maximum de fois où compresser doit être exécuté. Dans certains cas, plusieurs passes entraînent une compression supplémentaire du code. Gardez à l'esprit que plusieurs passes prendront plus de temps.properties
(par défaut :true
) -- réécriture de l'accès aux propriétés en utilisant la notation par points, par exemplefoo["bar"] → foo.bar
pure_funcs
(par défaut :null
) -- Vous pouvez transmettre un tableau de noms et UglifyJS supposera que ces fonctions ne produisent pas d'effets secondaires. DANGER : ne vérifiera pas si le nom est redéfini dans la portée. Un exemple de cas ici, par exemple.var q = Math.floor(a/b)
Si la variableq
est non utilisé ailleurs, UglifyJS le supprimera, mais conservera toujours leMath.floor(a/b)
, sans savoir ce qu'il fait. Vous pouvezpure_funcs: [ 'Math.floor' ]
lui faire savoir que cette fonction ne produira aucun effet secondaire, auquel cas l'instruction entière sera rejetée. l'implémentation actuelle ajoute une certaine surcharge (la compression sera plus lente). Assurez-vous que les symboles ci-dessouspure_funcs
sont également ci-dessousmangle.reserved
pour éviter toute modification.pure_getters
(par défaut :"strict"
) -- Si vous réussisseztrue
, UglifyJS supposera que l'accès aux propriétés de l'objet (par exemplefoo.bar
oufoo["bar"]
) n'a aucun effet secondaire. Spécifiez"strict"
de traiterfoo.bar
comme sans effet secondaire uniquement lorsqu'ilfoo
est certain de ne pas lancer, c'est-à-dire pasnull
ouundefined
.reduce_funcs
(par défaut :true
) - Permet d'intégrer des fonctions à usage unique en tant qu'expressions de fonction lorsque cela est autorisé, ce qui permet une optimisation ultérieure. Activé par défaut. L'option dépend dereduce_vars
son activation. Certains codes s'exécutent plus rapidement dans le moteur Chrome V8 si cette option est désactivée. Ne le fait pas avoir un impact négatif sur les autres principaux navigateurs.reduce_vars
(par défaut :true
) -- Améliore l'optimisation des variables affectées et utilisées comme valeurs constantes.sequences
(par défaut :true
) -- joint des instructions simples consécutives à l'aide de l'opérateur virgule. Peut être défini sur un entier positif pour spécifier le nombre maximum de séquences de virgules consécutives qui seront générées. Si cette option est définie sur,true
la limite par défautsequences
est200
. Définir l'option àfalse
ou0
à désactiver. La plus petitesequences
longueur est2
. Unesequences
valeur de1
est considérée comme équivalente àtrue
et en tant que telle signifie200
. En de rares occasions, la limite de séquences par défaut conduit à des temps de compression très lents, auquel cas une valeur de20
ou moins est recommandée.side_effects
(par défaut :true
) -- Transmissionfalse
pour désactiver la suppression potentielle des fonctions marquées comme « pures ». Un appel de fonction est marqué comme « pur » si une annotation de commentaire/*@__PURE__*/
ou/*#__PURE__*/
précède immédiatement l'appel. Par exemple :/*@__PURE__*/foo();
switches
(par défaut :true
) -- dédupliquer et supprimerswitch
les branches inaccessiblestoplevel
(par défaut :false
) -- supprime les fonctions non référencées ("funcs"
) et/ou les variables ("vars"
) dans la portée de niveau supérieur (false
par défaut,true
pour supprimer à la fois les fonctions et les variables non référencées)top_retain
(par défaut :null
) -- empêcheunused
la suppression de fonctions et de variables spécifiques de niveau supérieur (peut être un tableau, séparé par des virgules, RegExp ou une fonction. Impliestoplevel
)typeofs
(par défaut :true
) -- Se transformetypeof foo == "undefined"
enfoo === void 0
. Remarque : il est recommandé de définir cette valeur surfalse
pour IE10 et les versions antérieures en raison de problèmes connus.unsafe
(par défaut :false
) -- appliquer les transformations « dangereuses » (discussion ci-dessous)unsafe_comps
(par défaut :false
) -- compresse les expressions commea <= b
en supposant qu'aucun des opérandes ne peut être (contraint à)NaN
.unsafe_Function
(par défaut :false
) -- compresser et mutilerFunction(args, code)
lorsque lesargs
etcode
sont des chaînes littérales.unsafe_math
(par défaut :false
) -- optimise les expressions numériques comme2 * x * 3
into6 * x
, qui peuvent donner des résultats en virgule flottante imprécis.unsafe_proto
(par défaut :false
) -- optimise les expressions commeArray.prototype.slice.call(a)
into[].slice.call(a)
unsafe_regexp
(par défaut :false
) -- active les substitutions de variables avecRegExp
des valeurs de la même manière que s'il s'agissait de constantes.unsafe_undefined
(par défaut :false
) -- remplacervoid 0
s'il y a une variable nomméeundefined
dans la portée (le nom de la variable sera mutilé, généralement réduit à un seul caractère)unused
(par défaut :true
) -- supprime les fonctions et variables non référencées (les affectations de variables directes simples ne comptent pas comme des références à moins qu'elles ne soient définies sur"keep_assign"
)warnings
(par défaut :false
) -- afficher des avertissements lors de la suppression de code inaccessible ou de déclarations inutilisées, etc.
Options de déformation
eval
(par défautfalse
) -- Passertrue
aux noms mangle visibles dans les étendues oùeval
ouwith
sont utilisés.keep_fnames
(par défautfalse
) -- Passetrue
pour ne pas modifier les noms de fonctions. Utile pour le code reposant surFunction.prototype.name
. Voir aussi : l'keep_fnames
option compresser .reserved
(par défaut[]
) -- Transmettez un tableau d'identifiants qui doivent être exclus de la modification. Exemple :["foo", "bar"]
.toplevel
(par défautfalse
) -- Passertrue
aux noms mangle déclarés dans la portée de niveau supérieur.
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
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
(par défaut :false
) - Utilisétrue
pour permettre la modification des propriétés DOM intégrées. Il n'est pas recommandé de remplacer ce paramètre.debug
(par défaut :false
) -- Mangle les noms avec le nom d'origine toujours présent. Passez une chaîne vide""
pour activer, ou une chaîne non vide pour définir le suffixe de débogage.keep_quoted
(par défaut :false
) - Mangle uniquement les noms de propriétés sans guillemets.regex
(par défaut :null
) -- Transmettez un littéral RegExp pour modifier uniquement les noms de propriétés correspondant à l'expression régulière.reserved
(par défaut :[]
) -- Ne modifiez pas les noms de propriétés répertoriés dans lereserved
tableau.
Options de sortie
Le générateur de code essaie de générer le code le plus court possible par défaut. Si vous souhaitez une sortie embellie, transmettez --beautify
( -b
). Vous pouvez éventuellement transmettre des arguments supplémentaires qui contrôlent la sortie du code :
ascii_only
(par défautfalse
) -- échappe aux caractères Unicode dans les chaînes et les expressions rationnelles (affecte les directives dont les caractères non-ascii deviennent invalides)beautify
(par défauttrue
) -- s'il faut réellement embellir la sortie. La transmission-b
définira cela sur true, mais vous devrez peut-être passer-b
même lorsque vous souhaitez générer du code minifié, afin de spécifier des arguments supplémentaires, afin que vous puissiez les utiliser-b beautify=false
pour le remplacer.braces
(par défautfalse
) -- insérez toujours des accolades dans les instructionsif
,for
,do
ouwhile
,with
même si leur corps est une seule instruction.comments
(par défautfalse
) -- passeztrue
ou"all"
pour conserver tous les commentaires,"some"
pour conserver certains commentaires, une chaîne d'expression régulière (par exemple/^!/
) ou une fonction.indent_level
(défaut4
)indent_start
(par défaut0
) -- préfixez toutes les lignes par autant d'espacesinline_script
(par défauttrue
) -- échappe aux commentaires HTML et à la barre oblique dans les occurrences des</script>
chaînes inkeep_quoted_props
(par défautfalse
) -- lorsqu'il est activé, empêche la suppression des guillemets des noms de propriété dans les littéraux d'objet.max_line_len
(par défautfalse
) -- longueur de ligne maximale (pour le code mutilé)preamble
(par défautnull
) -- une fois transmis, il doit s'agir d'une chaîne et elle sera ajoutée littéralement au début de la sortie. La carte source s'adaptera à ce texte. Peut être utilisée pour insérer un commentaire contenant des informations de licence, par exemple.preserve_line
(par défautfalse
) -- passetrue
pour conserver les lignes, mais cela ne fonctionne que sibeautify
est défini surfalse
.quote_keys
(par défautfalse
) -- passetrue
pour citer toutes les clés dans les objets littérauxquote_style
(par défaut0
) -- style de guillemet préféré pour les chaînes (affecte également les noms de propriété et les directives cités) :0
-- préfère les guillemets doubles, passe aux guillemets simples lorsqu'il y a plus de guillemets doubles dans la chaîne elle-même.0
est préférable pour la taille gzip.1
-- utilisez toujours des guillemets simples2
-- utilisez toujours des guillemets doubles3
-- utilisez toujours les guillemets originaux
semicolons
(par défauttrue
) -- instructions séparées par des points-virgules. Si vous passez,false
chaque fois que cela est possible, nous utiliserons une nouvelle ligne au lieu d'un point-virgule, conduisant à une sortie plus lisible d'un code laid (la taille avant gzip pourrait être plus petite ; la taille après gzip insignifiante plus grande).shebang
(par défauttrue
) -- conserver le shebang#!
dans le préambule (scripts bash)webkit
(par défautfalse
) -- active les solutions de contournement pour les bogues WebKit. Les utilisateurs de PhantomJS doivent définir cette option surtrue
.width
(par défaut80
) -- ne prend effet que lorsque l'embellissement est activé, ceci spécifie une largeur de ligne (orientative) à laquelle l'embellisseur essaiera de respecter. Il fait référence à la largeur de la ligne de texte (hors indentation). Cela ne fonctionne pas très bien. actuellement, mais cela rend le code généré par UglifyJS plus lisible.wrap_iife
(par défautfalse
) -- passetrue
pour encapsuler les expressions de fonction immédiatement invoquées. Voir #640 pour plus de détails.
Divers
Keeping copyright notices or other comments
Vous pouvez passer --comments
pour conserver certains commentaires dans la sortie. Par défaut, les commentaires de style JSDoc qui contiennent "@preserve", "@license" ou "@cc_on" (compilation conditionnelle pour IE) seront conservés. Vous pouvez passer
--comments all
pour conserver tous les commentaires. commentaires, ou une expression rationnelle JavaScript valide pour conserver uniquement les commentaires qui correspondent à cette expression rationnelle. Par exemple, --comments /^!/
conservera les commentaires comme /*! Copyright Notice */
.
Notez cependant qu'il peut y avoir des situations dans lesquelles des commentaires sont perdus. Par exemple :
1
2
3
4
5
6
7function f() {
/** @preserve Foo Bar */
function g() {
// this function is never called
}
return something();
}
Même s'il contient "@preserve", le commentaire sera perdu car la fonction interne g
(qui est le nœud AST auquel le commentaire est attaché) est rejetée par le compresseur car non référencée.
Les commentaires les plus sûrs où placer les informations de copyright (ou d'autres informations qui doivent être conservées dans la sortie) sont les commentaires attachés aux nœuds de niveau supérieur.
L' unsafe
compress
option
Il permet certaines transformations qui pourraient briser la logique du code dans certains cas artificiels, mais cela devrait convenir à la plupart du code. Vous voudrez peut-être l'essayer sur votre propre code, cela devrait réduire la taille réduite. Voici ce qui se passe lorsque cet indicateur est activé :
new Array(1, 2, 3)
ouArray(1, 2, 3)
→[ 1, 2, 3 ]
new Object()
→{}
String(exp)
ouexp.toString()
→"" + exp
new Object/RegExp/Function/Error/Array (...)
→ on écarte lenew
Conditional compilation
Vous pouvez utiliser le commutateur --define
( -d
) afin de déclarer des variables globales qu'UglifyJS supposera être des constantes (sauf si elles sont définies dans la portée). Par exemple, si vous passez --define DEBUG=false
alors, couplé à la suppression du code mort, UglifyJS supprimera les éléments suivants de la sortie :
1
2
3if (DEBUG) {
console.log("debug stuff");
}
Vous pouvez spécifier des constantes imbriquées sous la forme --define env.DEBUG=false
.
UglifyJS avertira que la condition est toujours fausse et qu'il supprimera du code inaccessible ; pour l'instant, il n'y a pas d'option pour désactiver uniquement cet avertissement spécifique, vous pouvez passer warnings=false
pour désactiver tous les avertissements.
Une autre façon de procéder consiste à déclarer vos globales comme constantes dans un fichier séparé et à les inclure dans la construction. Par exemple, vous pouvez avoir un
build/defines.js
fichier avec ce qui suit :
1
2
3var DEBUG = false;
var PRODUCTION = true;
// etc.
et construisez votre code comme ceci :
1uglifyjs build/defines.js js/foo.js js/bar.js... -c
UglifyJS remarquera les constantes et, comme elles ne peuvent pas être modifiées, il évaluera les références à celles-ci à la valeur elle-même et supprimera le code inaccessible comme d'habitude. La construction contiendra les const
déclarations si vous les utilisez. Si vous ciblez des environnements <ES6, ce qui le fait ne prend pas en charge const
, l'utilisation var
de with reduce_vars
(activé par défaut) devrait suffire.
Conditional compilation API
Vous pouvez également utiliser la compilation conditionnelle via l'API programmatique. À la différence que le nom de la propriété est global_defs
et est une propriété de compresseur :
1
2
3
4
5
6
7
8var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
compress: {
dead_code: true,
global_defs: {
DEBUG: false
}
}
});
Pour remplacer un identifiant par une expression arbitraire non constante, il est nécessaire de préfixer la global_defs
clé avec "@"
pour demander à UglifyJS d'analyser la valeur en tant qu'expression :
1
2
3
4
5
6
7
8UglifyJS.minify("alert('hello');", {
compress: {
global_defs: {
"@alert": "console.log"
}
}
}).code;
// returns: 'console.log("hello");'
Sinon, il serait remplacé sous forme de chaîne littérale :
1
2
3
4
5
6
7
8UglifyJS.minify("alert('hello');", {
compress: {
global_defs: {
"alert": "console.log"
}
}
}).code;
// returns: '"console.log"("hello");'
Utilisation d'Uglify AST natif avecminify()
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 transversale et la transformation de l'AST natif peuvent être effectuées via
TreeWalker
et
TreeTransformer
respectivement.
ESTree / SpiderMonkey AST
UglifyJS a son propre format d'arbre de syntaxe abstraite ; pour des raisons pratiques, nous ne pouvons pas facilement passer à l'utilisation de SpiderMonkey AST en interne. Cependant, UglifyJS dispose désormais d'un convertisseur qui peut importer un SpiderMonkey AST.
Par exemple , Acorn est un analyseur ultra-rapide qui produit un AST SpiderMonkey. Il dispose d'un petit utilitaire CLI qui analyse un fichier et vide l'AST au format JSON sur la sortie standard. Pour utiliser UglifyJS pour modifier et compresser cela :
1acorn file.js | uglifyjs -p spidermonkey -m -c
L' -p spidermonkey
option indique à UglifyJS que tous les fichiers d'entrée ne sont pas du JavaScript, mais du code JS décrit dans SpiderMonkey AST en JSON. Par conséquent, nous n'utilisons pas notre propre analyseur dans ce cas, mais transformons simplement cet AST en notre AST interne.
Use Acorn for parsing
Plus pour le plaisir, j'ai ajouté l' -p acorn
option qui utilisera Acorn pour faire toute l'analyse. Si vous passez cette option, UglifyJS le fera require("acorn")
.
Acorn est très rapide (par exemple 250 ms au lieu de 380 ms sur du code de 650 Ko), mais la conversion de l'arbre SpiderMonkey produit par Acorn prend 150 ms supplémentaires, donc au total, c'est un peu plus que simplement utiliser le propre analyseur d'UglifyJS.
Uglify Fast Minify Mode
Ce n'est pas bien connu, mais la suppression des espaces et la modification des symboles représentent 95 % de la réduction de la taille du code minifié pour la plupart des JavaScript - et non des transformations de code élaborées. On peut simplement les désactiver compress
pour accélérer les builds Uglify de 3 à 4 fois mangle
. seul le mode Uglify a des vitesses de minification et des tailles de gzip comparables à
butternut
:
d3.js | réduire la taille | taille du zip | réduire le temps (secondes) |
---|---|---|---|
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 |
Pour activer le mode de réduction rapide à partir de la CLI, utilisez :
1uglifyjs file.js -m
Pour activer le mode de réduction rapide avec l'API, utilisez :
1UglifyJS.minify(code, { compress: false, mangle: true });
Cartes sources et débogage
Diverses compress
transformations qui simplifient, réorganisent, intègrent et suppriment du code sont connues pour avoir un effet négatif sur le débogage avec les mappages sources. Ceci est normal car le code est optimisé et les mappages sont souvent tout simplement impossibles car une partie du code n'existe plus. le débogage de la carte désactive l' compress
option Uglify et utilise simplement mangle
.
Compiler assumptions
Pour permettre de meilleures optimisations, le compilateur fait diverses hypothèses :
.toString()
et.valueOf()
n'ont pas d'effets secondaires, et pour les objets intégrés, ils n'ont pas été remplacés.undefined
,NaN
etInfinity
n'ont pas été redéfinis en externe.arguments.callee
,arguments.caller
etFunction.prototype.caller
ne sont pas utilisés.- Le code ne s'attend pas à ce que le contenu
Function.prototype.toString()
soitError.prototype.stack
quelque chose de particulier. - L'obtention et la définition de propriétés sur un objet simple ne provoquent pas d'autres effets secondaires (en utilisant
.watch()
ouProxy
). - Les propriétés des objets peuvent être ajoutées, supprimées et modifiées (non empêchées avec
,
Object.defineProperty()
,Object.defineProperties()
ou ) .Object.freeze()
Object.preventExtensions()
Object.seal()