Module communautaire génial

UglifyJS 3

UglifyJS est une boîte à outils d'analyse, de minimisation, de compression et d'embellissement JavaScript.

Noter:

  • uglify-js@3a une API et une CLI simplifiées qui ne sont pas rétrocompatibles avecuglify-js@2 .
  • La documentation pour les 2.xversions d' UglifyJS peut être trouvée ici .
  • uglify-js ne prend en charge que JavaScript (ECMAScript 5).
  • Pour minifier ECMAScript 2015 ou supérieur, transpilez à l'aide d'outils comme Babel .

Installer

Assurez-vous d'abord que vous avez installé la dernière version de node.js (vous devrez peut-être redémarrer votre ordinateur après cette étape).

À partir de NPM pour une utilisation en tant qu'application de ligne de commande :

1
npm install uglify-js -g

De NPM pour une utilisation programmatique :

1
npm install uglify-js

Utilisation de la ligne de commande

1
uglifyjs [input files] [options]

UglifyJS peut prendre plusieurs fichiers d'entrée. Il est recommandé de transmettre d'abord les fichiers d'entrée, puis 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 sera correctement mis en correspondance.

Si aucun fichier d'entrée n'est spécifié, UglifyJS lira à partir de 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 :

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.

Spécifiez --output( -o) pour déclarer le fichier de sortie. Sinon, la sortie passe à STDOUT.

Options de carte 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, passez --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ù se trouvent les fichiers originaux.

  • --source-map "url='<URL>'"pour spécifier l'URL où se trouve la carte source. Sinon, UglifyJS suppose que HTTP X-SourceMapest utilisé et omettra la //# sourceMappingURL=directive.

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

Ce qui précède va compresser et déformer file1.jset file2.js, va déposer la sortie dans foo.min.jset la carte source dans foo.min.js.map. Le mappage source fera référence à http://foo.com/src/js/file1.jset 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 d'origine comme js/file1.jset js/file2.js).

Composed source map

Lorsque vous compressez du code JS 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 mapper vers le code d'origine (c'est-à-dire CoffeeScript). UglifyJS a un option pour prendre une carte source d'entrée.En supposant que vous ayez un mappage de CoffeeScript → JS compilé, UglifyJS peut générer une carte 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 de l'interface de ligne de commande

Vous devez passer --compress( -c) pour activer le compresseur. Vous pouvez éventuellement passer une liste d' options de compression séparées par des virgules .

Les options sont sous la forme foo=bar, ou simplement foo(cette dernière implique une option booléenne que vous souhaitez définir true; c'est en fait un raccourci pour foo=true).

Exemple:

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

Options de modification de l'interface de ligne de commande

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éfaut false) - mangle les noms déclarés dans la portée de niveau supérieur.

  • eval(par défaut false) - les noms mutilés sont visibles dans les portées où evalou withsont utilisés.

Lorsque la mutilation est activée mais que vous voulez empêcher certains noms d'être mutilés, vous pouvez déclarer ces noms avec --mangle reserved— passer une liste de noms séparés par des virgules. Par exemple :

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

pour empêcher que les noms require, exportset $ne soient modifiés.

Noms de propriété de modification de l'interface de ligne de commande ( --mangle-props)

Remarque : CECI BRISERA PROBABLEMENT 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-propspour l'activer. Cela modifiera toutes les propriétés du code d'entrée à l'exception des propriétés DOM intégrées et des propriétés du noyau JavaScript 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
1
var 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 reservedpropriétés :

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

Mangle toutes les propriétés correspondant à un 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());

Combinaison d'options de propriétés de mangle :

1
$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
1
var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());

Pour que cela soit utile, nous évitons de modifier les noms JS standard par défaut ( --mangle-props builtinsà remplacer).

Un fichier d'exclusion par défaut est fourni tools/domprops.jsonet devrait couvrir la plupart des propriétés JS et DOM standard définies dans divers navigateurs. Passez --mangle-props dompropspour désactiver cette fonctionnalité.

Une expression régulière peut être utilisée pour définir quels noms de propriété doivent être modifiés. Par exemple, --mangle-props regex=/^_/ne modifiera que les noms de propriété commençant par un trait de soulignement.

Lorsque vous compressez plusieurs fichiers à l'aide de cette option, pour qu'ils fonctionnent ensemble à la fin, nous devons nous assurer qu'une propriété est mutilée avec le même nom dans --name-cache filename.json tous.Pour cela, pass et UglifyJS maintiendront 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

Maintenant, part1.jset part2.jsseront 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.

Détruire les noms sans guillemets ( --mangle-props keep_quoted)

L'utilisation du nom de propriété entre guillemets ( o["foo"]) réserve le nom de la propriété ( foo) afin qu'il ne soit pas mutilé dans tout le 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
1
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);

Debugging property name mangling

Vous pouvez également passer --mangle-props debugafin 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
1
var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);

Vous pouvez également transmettre un suffixe personnalisé à l'aide de --mangle-props debug=XYZ. Cela modifierait ensuite la valeur o.fooen 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 la 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 les erreurs telles que l'écriture de clés mutilées dans le stockage.

Référence API

En supposant l'installation via NPM, vous pouvez charger UglifyJS dans votre application comme ceci :

1
var 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(), activera les options compress et 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}

Vous pouvez minifyutiliser 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 du code source :

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' topleveloption :

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' nameCacheoption :

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

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

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

Pour produire des avertissements :

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'erreur :

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}

Remarque : contrairement à `uglify-js@2.x, the 3.x`, l'API ne génère pas d'erreurs. Pour obtenir un effet similaire, procédez comme suit :

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

Options de réduction

  • warnings(par défaut false) — passez truepour renvoyer les avertissements du compresseur dans result.warnings. Utilisez la valeur "verbose"pour des avertissements plus détaillés.

  • parse(par défaut {}) — passez un objet si vous souhaitez spécifier des options d'analyse supplémentaires .

  • compress(valeur par défaut {}) : passez falsepour ignorer complètement la compression. Transmettez un objet pour spécifier les options de compression personnalisées .

  • mangle(par défaut true) — passer falsepour ignorer les noms de mangle, ou passer un objet pour spécifier les options de mangle (voir ci-dessous).

    • mangle.properties(par défaut false) — une sous-catégorie de l'option mangle. Passez un objet pour spécifier les options de propriété mangle personnalisées .
  • output(default null) — 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éfaut false)-passez un objet si vous souhaitez spécifier des options de carte source .

  • toplevel(par défaut false)-définir sur truesi vous souhaitez activer la modification de niveau supérieur des noms de variables et de fonctions et supprimer les variables et fonctions inutilisées.

  • nameCache(par défaut null)-passez un objet vide {}ou un objet précédemment utilisé nameCachesi vous souhaitez mettre en cache les noms de variables et de propriétés mutilés sur plusieurs appels de minify(). 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é de manière externe par l'utilisateur.

  • ie8(par défaut false)-définir sur truepour prendre en charge IE8.

  • keep_fnames(par défaut : false)-pass truepour empêcher la suppression ou la modification des noms de fonction. Utile pour le code s'appuyant sur Function.prototype.name.

Minifier 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 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

Notez que la carte source n'est pas enregistrée dans un fichier, elle est simplement renvoyée dans result.map. La valeur passée pour sourceMap.urln'est utilisée que pour définir //# sourceMappingURL=out.js.mapdans result.code. La valeur de filenameest uniquement utilisée pour définir l' fileattribut (voir la spécification ) dans le fichier de carte source.

Vous pouvez définir l'option sourceMap.urlsur être "inline"et la carte source sera ajoutée au code.

Vous pouvez également spécifier la propriété sourceRoot à inclure dans la carte source :

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 vous compressez du JavaScript compilé et que vous avez une carte source pour cela, vous pouvez utiliser 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 vous utilisez X-SourceMapplutôt l'en- tête, vous pouvez simplement omettre sourceMap.url.

Options d'analyse

  • bare_returns(par défaut false) - prend en charge les returninstructions de niveau supérieur

  • html5_comments(par défaut true)

  • shebang(par défaut true) - prise #!commanden charge comme première ligne

Options de compression

  • arguments(par défaut :) true- remplacer arguments[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:) - applique 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:) - applique les optimisations pour if-s et les expressions conditionnelles

  • dead_code(par défaut true:) - supprimer le code inaccessible

  • drop_console(par défaut :) false- Passer truepour ignorer les appels aux console.*fonctions. Si vous souhaitez supprimer un appel de fonction spécifique tel que console.infoet/ou conserver les effets secondaires des arguments de fonction après avoir supprimé l'appel de fonction, utilisez à la pure_funcsplace.

  • drop_debugger(par défaut :) true- supprimer les debugger;instructions

  • evaluate(par défaut true:) - tente d'évaluer les expressions constantes

  • expression(par défaut :) false- Passer truepour préserver les valeurs de complétion des instructions de terminal sans return, par exemple dans les bookmarklets.

  • global_defs(par défaut :){} - voir compilation conditionnelle

  • hoist_funs(par défaut false:) - déclarations de fonction de levage

  • hoist_props(par défaut true:) - hisse les propriétés d'objets constants et de littéraux de tableau en variables régulières soumises à un ensemble de contraintes. Par exemple : var o={p:1, q:2}; f(o.p, o.q);est converti en f(1, 2);. Remarque : hoist_props fonctionne mieux avec mangleactivé, l' compressoption passesdéfinie sur 2ou supérieure et l' compressoption toplevelactivée.

  • hoist_vars(par défaut false:) - vardéclarations de hoist (c'est false 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/continue

  • inline(par défaut true:) - appels en ligne à la fonction avec l' returninstruction simple/ :

    • false - pareil que 0
    • 0 - inline désactivé
    • 1 - fonctions simples en ligne
    • 2 - fonctions en ligne avec arguments
    • 3 - fonctions en ligne avec arguments et variables
    • true - pareil que 3
  • join_vars(par défaut true:) - joindre des varinstructions consécutives

  • keep_fargs(par défaut true:) - Empêche le compresseur de supprimer les arguments de fonction inutilisés. Vous en avez besoin pour le code qui repose sur Function.length.

  • keep_fnames(par défaut :) false- Passe truepour empêcher le compresseur d'ignorer les noms de fonction. Utile pour le code s'appuyant sur Function.prototype.name. Voir aussi : l' keep_fnames option mangle .

  • keep_infinity(par défaut :) false- Passez truepour éviter Infinityd'être compressé dans 1/0, ce qui peut entraîner des problèmes de performances sur Chrome.

  • loops(par défaut true:) - optimisations pour do, whileet forboucles lorsque nous pouvons déterminer statiquement la condition.

  • negate_iife(par défaut true:) - annule les "Expressions de fonction appelées immédiatement" 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 maximal d'exécutions de la compression. Dans certains cas, plus d'une passe entraîne une compression supplémentaire du code. Gardez à l'esprit que plus de passes prendront plus de temps.

  • properties(par défaut true:) - réécrire 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 passer 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 cas d'exemple ici, par exemple var q = Math.floor(a/b). Si la variable qn'est pas utilisé ailleurs, UglifyJS le supprimera, mais conservera toujours le Math.floor(a/b), ne sachant pas ce qu'il fait. Vous pouvez passer pure_funcs: [ 'Math.floor' ]pour lui faire savoir que cette fonction ne produira aucun effet secondaire, auquel cas l'ensemble de l'instruction serait rejeté. L'implémentation ajoute un peu de surcharge (la compression sera plus lente). Assurez-vous que les symboles sous pure_funcs sont également sous mangle.reservedpour éviter de mutiler.

  • pure_getters(par défaut :) "strict"- Si vous passez truepour cela, UglifyJS supposera que l'accès aux propriétés de l'objet (par exemple foo.barou foo["bar"]) n'a aucun effet secondaire. Spécifiez "strict"de traiter foo.barcomme sans effet secondaire uniquement lorsqu'il fooest certain de ne pas lancer, c'est-à-dire pas nullou undefined.

  • reduce_funcs(par défauttrue :) - Permet aux fonctions à usage unique d'être incorporées en tant qu'expressions de fonction lorsque cela est autorisé, ce qui permet une optimisation supplémentaire. Activé par défaut. L'option dépend de reduce_vars son activation. Certains codes s'exécutent plus rapidement dans le moteur Chrome V8 si cette option est désactivée. Pas négativement impact 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 maximal de séquences de virgules consécutives qui seront générées. Si cette option est définie sur truealors la sequenceslimite par défaut est 200. Définissez l'option sur falseou 0 pour désactiver. La plus petite sequenceslongueur est 2. Une sequencesvaleur de 1 est protégée pour être équivalente à trueet en tant que telle signifie 200. Dans de rares occasions, la limite de séquences par défaut conduit à des temps de compression très lents, auquel cas une valeur de 20ou moins est recommandée.

  • side_effects(par défaut :) true- Passe falsepour désactiver les fonctions potentiellement abandon marquées comme « pure » Un appel de fonction est marqué comme « pure » 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édupliquez et supprimez les switchbranches inaccessibles

  • toplevel(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 ( falsepar défaut, truepour supprimer à la fois les fonctions et les variables non référencées)

  • top_retain(par défaut null:) - empêche la unusedsuppression de fonctions et de variables de niveau supérieur spécifiques (peut être un tableau, séparé par des virgules, RegExp ou une fonction. Implique toplevel)

  • typeofs(par défaut :)true - Se transforme typeof foo == "undefined"en foo === void 0. Remarque : il est recommandé de définir cette valeur sur falsepour IE10 et les versions antérieures en raison de problèmes connus.

  • unsafe(par défaut false:) - appliquer des transformations "non sécurisées" (discussion ci-dessous)

  • unsafe_comps(par défaut :) false- compresse les expressions comme a <= bsupposer qu'aucun des opérandes ne peut être (contraint à) NaN.

  • unsafe_Function(par défaut false:) - compresse et mangle Function(args, code) lorsque les deux argset codesont des littéraux de chaîne.

  • unsafe_math(par défaut false:) - optimise les expressions numériques comme 2 * x * 3into 6 * x, ce qui peut donner des résultats en virgule flottante imprécis.

  • unsafe_proto(par défaut false:) - optimise les expressions comme Array.prototype.slice.call(a)dans[].slice.call(a)

  • unsafe_regexp(par défaut false:) - active les substitutions de variables avec des RegExpvaleurs de la même manière que s'il s'agissait de constantes.

  • unsafe_undefined(par défaut false:) - remplacer void 0s'il y a une variable nommée undefineddans 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 références à moins qu'elles ne soient définies sur "keep_assign")

  • warnings(par défaut false:) - affiche des avertissements lors de la suppression de code inaccessible ou de déclarations inutilisées, etc.

Options de mutilation

  • eval(par défaut false) - Passer trueaux noms de mangle visibles dans les portées où evalou withsont utilisés.

  • keep_fnames(par défaut false) - Passer truepour ne pas modifier les noms de fonction. Utile pour le code s'appuyant sur Function.prototype.name. Voir aussi : l' keep_fnames option compress .

  • reserved(par défaut []) - Pass AN BE Should Tableau d'identifiants dont la modification est exclue Exemple : ["foo", "bar"]. .

  • toplevel(par défaut false) - Passer trueaux 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 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(par défaut :) false- À utiliser truepour autoriser la modification des propriétés DOM intégrées. Il n'est pas recommandé de remplacer ce paramètre.

  • debug(par défautfalse :) -— Manglez 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:) -— Ne modifiez que les noms de propriétés sans guillemets.

  • regex(par défaut null:) -— Transmettez un littéral RegExp aux seuls noms de propriété mangle correspondant à l'expression régulière.

  • reserved(par défaut []:) - Ne modifie pas les noms de propriétés répertoriés dans le reservedtableau.

Options de sortie

Le générateur de code essaie de sortir le code le plus court possible par défaut. Si vous voulez une sortie embellie, passez --beautify( -b). Vous pouvez éventuellement passer des arguments supplémentaires qui contrôlent la sortie du code :

  • ascii_only(par défaut false) - échappe les caractères Unicode dans les chaînes et les expressions régulières (affecte les directives avec des caractères non ASCII devenant invalides)

  • beautify(par défaut true) - s'il faut réellement embellir la sortie. Le passage -bdéfinira cela sur vrai, mais vous devrez peut-être passer -bmême lorsque vous souhaitez générer du code minifié, afin de spécifier des arguments supplémentaires, afin que vous puissiez l'utiliser -b beautify=falsepour le remplacer.

  • braces(par défaut false) - Toujours dans les accolades INSERT if, for, do, whileou les withinstructions, l'instruction même Leur corps EST UNE SINGLE IF.

  • comments(default false) - passer trueou "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(par défaut 4)

  • indent_start(par défaut 0) - préfixe toutes les lignes par autant d'espaces

  • inline_script(par défaut true) - échappe aux commentaires HTML et à la barre oblique dans les occurrences de </script>dans les chaînes

  • keep_quoted_props(par défaut false) - lorsqu'il est activé, empêche de supprimer les guillemets des noms de propriété dans les littéraux d'objet.

  • max_line_len(par défaut false) - longueur de ligne maximale (pour le code uglified)

  • preamble(par défaut null) - lorsqu'il est passé, il doit s'agir d'une chaîne et il sera ajouté littéralement à la sortie. La carte source s'ajustera à ce texte. Peut être utilisé pour insérer un commentaire contenant des informations de licence, par exemple.

  • preserve_line(par défaut false) - passer truepour conserver les lignes, mais cela ne fonctionne que si beautifyest défini sur false.

  • quote_keys(par défaut false) - passer truepour citer toutes les clés dans les objets littéraux

  • quote_style(par défaut 0) - style de guillemet préféré pour les chaînes (affecte également les noms de propriétés et les directives entre guillemets) :

    • 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. 0est préférable pour la taille de gzip.
    • 1 - toujours utiliser des guillemets simples
    • 2 - toujours utiliser des guillemets doubles
    • 3 - toujours utiliser les citations originales
  • semicolons(par défaut true) - instructions séparées avec des points-virgules. Si vous passez falsealors chaque fois que possible, nous utiliserons une nouvelle ligne au lieu d'un point-virgule, ce qui entraînera une sortie plus lisible du code uglifié (la taille avant gzip pourrait être plus petite; la taille après gzip n'est pas significativement plus grande).

  • shebang(par défaut true) - conserve shebang #!dans le préambule (scripts bash)

  • webkit(par défaut false) - activez les solutions de contournement pour les bogues WebKit. Les utilisateurs de PhantomJS doivent définir cette option sur true.

  • width(par défaut 80) - ne prend effet que lorsque l'embellissement est activé, cela spécifie une largeur de ligne (orientative) à laquelle l'embellisseur essaiera d'obéir. Cela fait référence à la largeur du texte de la ligne (à l'exclusion de l'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éfaut false) - passe truepour envelopper les expressions de fonction immédiatement invoquées. Voir #640 pour plus de détails.

Divers

Vous pouvez transmettre --commentspour conserver certains commentaires dans la sortie. Par défaut, il conservera les commentaires de style JSDoc contenant "@preserve", "@license" ou "@cc_on" (compilation conditionnelle pour IE). Vous pouvez transmettre --comments allpour conserver tous les commentaires, ou une expression rationnelle JavaScript valide pour ne conserver que les commentaires qui correspondent à cette expression rationnelle. Par exemple --comments /^!/ , conservera les commentaires tels que /*! Copyright Notice */.

Notez, cependant, qu'il peut y avoir des situations où les commentaires sont perdus. Par exemple :

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

Même s'il a "@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 comme 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 des commentaires attachés aux nœuds de niveau supérieur.

L' unsafe compressoption

Il permet certaines transformations qui peuvent casser la logique du code dans certains cas artificiels, mais devrait convenir à la plupart des codes. 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)ou Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp)ou exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...) → on écarte le new

Conditional compilation

Vous pouvez utiliser le commutateur --define( -d) pour déclarer des variables globales que UglifyJS supposera être des constantes (sauf si elles sont définies dans la portée). Par exemple, si vous passez --define DEBUG=falsealors, couplé à la suppression du code mort, UglifyJS supprimera les éléments suivants de la sortie :

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

Vous pouvez spécifier des constantes imbriquées sous la forme de --define env.DEBUG=false.

UglifyJS avertira que la condition est toujours fausse et que le code est inaccessible ; pour l'instant, il n'y a pas d'option pour désactiver uniquement cet avertissement spécifique, vous pouvez passer warnings=falsepour désactiver tous les avertissements.

Une autre façon de le faire est de déclarer vos globales en tant que constantes dans un fichier séparé et de l'inclure dans la construction. Par exemple, vous pouvez avoir un build/defines.jsfichier avec les éléments suivants :

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

et construis ton code comme ceci :

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

UglifyJS remarquera les constantes et, puisqu'elles ne peuvent pas être modifiées, il évaluera les références à la valeur elle-même et supprimera le code inaccessible comme d'habitude. La construction contiendra les constdéclarations si vous les utilisez. Si vous ciblez les environnements <ES6 qui ne not support const, l'utilisation de varwith reduce_vars(activé par défaut) devrait suffire.

Conditional compilation API

Vous pouvez également utiliser la compilation conditionnelle via l'API de programmation, à la différence que le nom de la propriété est global_defset est une propriété de compresseur :

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

Pour remplacer un identifiant par une expression arbitraire non constante, il est nécessaire de préfixer la global_defsclé avec "@"pour indiquer à UglifyJS d'analyser la valeur en tant qu'expression :

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

Sinon, il serait remplacé par un littéral de chaîne :

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

Utiliser Uglify AST natif avec 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 transversalité et la transformation de l'AST native peuvent être effectuées via TreeWalkeret 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 l'AST SpiderMonkey en interne. Cependant, UglifyJS dispose maintenant d'un convertisseur qui peut importer un AST SpiderMonkey.

Par exemple, Acorn est un analyseur ultra-rapide qui produit un SpiderMonkey AST. Il possède un petit utilitaire CLI qui analyse un fichier et vide l'AST en JSON sur la sortie standard. Pour utiliser UglifyJS pour modifier et compresser cela :

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

L' -p spidermonkeyoption indique à UglifyJS que tous les fichiers d'entrée ne sont pas du code 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 acornoption qui utilisera Acorn pour faire tout 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 un code de 650 K), mais la conversion de l'arbre SpiderMonkey produit par Acorn prend 150 ms supplémentaires, donc au total, c'est un peu plus que d'utiliser le propre analyseur d'UglifyJS.

Uglify Fast Minify Mode

Ce ne sont pas bien connus, mais les espaces suppression et symboles mutiler comptes pour 95% à la réduction de taille dans le code minified pour JavaScript PLUS -. Ne développerons pas le code du TRANSFORMS On peut simplement désactiver compresspour accélérer construit enlaidir de 3 à 4 fois par En c'est le RAPIDE. mangle- seul le mode Uglify a des vitesses de minification et des tailles de gzip comparables à butternut :

d3.js réduire la taille taille gzip minifier 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
noyer cendré@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 minification rapide à partir de la CLI, utilisez :

1
uglifyjs file.js -m

Pour activer le mode de minification rapide avec l'API, utilisez :

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

Cartes sources et débogage

Diverses compresstransformations qui simplifient, réorganisent, inline et suppriment le code sont connues pour avoir un effet négatif sur le débogage avec les mappages de source.Cela est attendu car le code est optimisé et les mappages sont souvent tout simplement impossibles car certains codes n'existent plus.Pour une fidélité maximale dans la source le débogage de la carte désactive l' compressoption Uglify et utilise simplementmangle .

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 et Infinityn'ont pas été redéfinis en externe.
  • arguments.callee, arguments.caller et Function.prototype.callerne sont pas utilisés.
  • Le code n'attend pas le contenu de Function.prototype.toString() ou Error.prototype.stacksoit quelque chose de particulier.
  • Obtenir et définir des propriétés sur un objet simple ne provoque pas d'autres effets secondaires (en utilisant .watch() ou Proxy).
  • Peut être ajouté l'objet Propriétés, retiré et modifié (pas empêché avec Object.defineProperty(), Object.defineProperties(), Object.freeze(), Object.preventExtensions()ou Object.seal()).