Module communautaire génial

UglifyJS 3

UglifyJS est une boîte à outils pour analyseur, minificateur, compresseur et embellisseur JavaScript.

Remarque:

  • uglify-js@3 possède une API et une CLI simplifiées qui ne sont pas rétrocompatibles avec uglify-js@2 .
  • La documentation des versions d'UglifyJS 2.x peut être trouvée ici .
  • uglify-js ne prend en charge que JavaScript (ECMAScript 5).
  • To minify ECMAScript 2015 or above , transpilez à l'aide d'outils tels que 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

Depuis 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 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 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 va à 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, 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 HTTP X-SourceMap est utilisé et omettra la directive //# sourceMappingURL= .

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 compressera et mangle file1.js et file2.js , supprimera la sortie dans foo.min.js et la carte source dans foo.min.js.map . Le mappage des sources se référera à http://foo.com/src/js/file1.js et http://foo.com/src/js/file2.js (en fait, il http://foo.com/src/js/file1.js http://foo.com/src comme racine de la carte source, et les fichiers d'origine comme js/file1.js et js/file2.js ).

Composed source map

Lorsque vous compressez du code JS qui a été produit par un compilateur tel que CoffeeScript, le mappage au code JS ne sera pas trop utile. Au lieu de cela, vous aimeriez revenir au code d'origine (par exemple CoffeeScript). UglifyJS a un 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 CLI

Vous devez passer --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 voulez définir true ; c'est en fait un raccourci pour foo=true ).

Exemple:

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

Options de mangle de la CLI

Pour activer le mangler, vous devez passer --mangle ( -m ). Les options suivantes (séparées par des virgules) sont prises en charge:

  • toplevel ( false par défaut) - noms de mangle déclarés dans la portée de niveau supérieur.

  • eval ( false par défaut) - mangle les noms visibles dans les portées où eval ou with sont utilisés.

Lorsque le découpage est activé mais que vous souhaitez éviter que certains noms ne soient 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 éviter que les noms require , exports et $ ne soient modifiés.

Modification des noms de propriétés de la CLI ( --mangle-props )

Remarque: CECI BRISERA PROBABLEMENT VOTRE CODE. La gestion des noms de propriétés est une étape distincte, différente de celle 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 DOM intégrées et les propriétés des classes JavaScript principales. 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 (à l'exception des fonctions builtins JavaScript):

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 propriétés reserved :

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 à une 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 des 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 dans tools/domprops.json qui 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 les noms de propriété à modifier. 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é soit mutilée avec le même nom dans tous. Pour cela, transmettez --name-cache filename.json et UglifyJS conservera ces mappages dans un fichier qui pourra 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 et 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.

Gestion des noms sans --mangle-props keep_quoted ( --mangle-props keep_quoted )

L'utilisation du nom de propriété entre guillemets ( o["foo"] ) réserve le nom de propriété ( foo ) afin qu'il ne soit pas mutilé dans tout le script, même lorsqu'il est utilisé dans un style non o.foo ( 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 le --mangle-props debug afin de modifier les noms de propriétés sans les o.foo complètement. Par exemple, la propriété o.foo serait o.foo en o._$foo$_ avec cette option. Cela permet de modifier les propriétés d'une base de code volumineuse tout en étant toujours en mesure de déboguer le code et d'identifier les endroits où la déformation brise 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 o.foo alors o.foo en o._$foo$XYZ_ . Vous pouvez changer cela chaque fois que vous compilez un script pour identifier comment une propriété a été mutilée Une technique consiste à passer un nombre aléatoire sur chaque compilation pour simuler la modification de la modification avec différentes 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 vers 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() 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 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 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'option de niveau toplevel :

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'option nameCache :

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

Un exemple de combinaison d'options minify() :

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 API 3.x` ne génère pas d'erreurs. Pour obtenir un effet similaire, vous pouvez procéder comme suit:

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

Options de réduction

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

  • parse (default {} ) - passe un objet si vous souhaitez spécifier des options d'analyse supplémentaires .

  • compress (default {} ) - transmettez false pour ignorer complètement la compression. Passez un objet pour spécifier les options de compression personnalisées.

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

    • mangle.properties ( false par défaut) - 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 ) - transmet 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 ( false par défaut) -passez un objet si vous souhaitez spécifier les options de la carte source .

  • toplevel ( false par défaut) toplevel à true si vous souhaitez activer la variable de niveau supérieur et la gestion des noms de fonction et supprimer les variables et fonctions inutilisées.

  • nameCache (valeur null par défaut) nameCache un objet vide {} ou un objet nameCache précédemment utilisé si vous souhaitez mettre en cache les noms de variables et de propriétés mutilés à travers plusieurs minify() de minify() . Remarque: il s'agit d'une propriété en lecture / écriture. minify() va lire l'état du cache de noms de cet objet et le mettre à jour pendant la minification afin qu'il puisse être réutilisé ou conservé en externe par l'utilisateur.

  • ie8 ( false par défaut) -set à true pour prendre en charge IE8.

  • keep_fnames (par défaut: false ) -pass true pour éviter de supprimer ou de modifier les noms de fonctions. Utile pour le code reposant sur Function.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 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 transmise pour sourceMap.url est uniquement utilisée pour définir //# sourceMappingURL=out.js.map dans result.code . La valeur de filename n'est utilisé que pour définir l'attribut de file (voir la spécification ) dans le fichier de carte source.

Vous pouvez définir l'option sourceMap.url comme étant "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 disposez d'une carte source, 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 plutôt l'en X-SourceMap tête X-SourceMap , vous pouvez simplement omettre sourceMap.url .

Options d'analyse

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

  • html5_comments ( true par défaut)

  • shebang ( true par défaut) - prend en charge la #!command comme première ligne

Options de compression

  • arguments (par défaut: true ) - remplacez 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éduit 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 , tente de nier les nœuds binaires, par exemple a = !b && !c && !d && !e → a=!(b||c||d||e) etc.

  • conditionals (par défaut: true ) - applique des optimisations pour if -s et expressions conditionnelles

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

  • drop_console (par défaut: false ) - Passez true pour ignorer les appels aux fonctions console.* . Si vous souhaitez supprimer un appel de fonction spécifique tel que console.info et / ou conserver les effets secondaires des arguments de fonction après avoir abandonné l'appel de fonction, utilisez pure_funcs au lieu.

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

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

  • expression (par défaut: false ) - Passez true pour conserver 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 des objets constants et des littéraux de tableau dans des variables régulières soumises à un ensemble de contraintes. Par exemple: var o={p:1, q:2}; f(op, oq); is converti en f(1, 2); Remarque: hoist_props fonctionne mieux avec mangle activé, l'option compress passes définie à 2 ou plus et l'option compress toplevel activée.

  • hoist_vars (par défaut: false ) - déclarations de var hoist_vars (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 pour fonctionner avec une instruction simple / return :

    • false - identique à 0
    • 0 - inlining désactivé
    • 1 - fonctions simples en ligne
    • 2 - fonctions en ligne avec arguments
    • 3 - Fonctions en ligne avec arguments et variables
    • true - identique à 3
  • join_vars (par défaut: true ) - joint des instructions var consécutives

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

  • keep_fnames (par défaut: false ) - Passez true pour empêcher le compresseur de rejeter les noms de fonctions. Utile pour le code reposant sur Function.prototype.name . Voir aussi: l' option mangle keep_fnames .

  • keep_infinity (par défaut: false ) - Passez true pour empêcher Infinity d'être compressé en 1/0 , ce qui peut entraîner des problèmes de performances sur Chrome.

  • loops (par défaut: true ) - optimisations pour do boucles do , while et for 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ère.

  • passes (par défaut: 1 ): nombre maximal d'exécutions de compress. Dans certains cas, plusieurs passes entraînent une compression supplémentaire du code. Gardez à l'esprit que plus de passes prendront plus de temps.

  • properties (par défaut: true ) - réécrit l'accès aux propriétés en utilisant la notation par points, par exemple foo["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 exemple de cas ici, par exemple var q = Math.floor(a/b) . Si la variable q n'est pas utilisée ailleurs, UglifyJS la supprimera, mais gardera toujours le Math.floor(a/b) , sans savoir 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'instruction entière sera supprimée. L'implémentation actuelle ajoute une surcharge (la compression sera plus lente). Assurez-vous que les symboles sous pure_funcs sont également sous mangle.reserved pour éviter la mutilation.

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

  • reduce_funcs (par défaut: true ) - 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 l' reduce_vars de reduce_vars . Certains codes s'exécutent plus rapidement dans le moteur Chrome V8 si cette option est désactivée . N'a pas d'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 maximal de séquences de virgules consécutives qui seront générées. Si cette option est définie sur true la limite des sequences par défaut est 200 Définissez l'option sur false ou sur 0 pour désactiver. La plus petite longueur des sequences est 2 Une valeur de sequences de 1 est acquise pour être équivalente à true et signifie donc 200 En de rares occasions, la limite de séquences par défaut entraîne des temps de compression très lents auquel cas une valeur de 20 ou moins est recommandée.

  • side_effects (par défaut: true ) - Passez false pour désactiver les fonctions potentiellement abandonnées 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 le call. Par exemple: /*@__PURE__*/foo();

  • switches (par défaut: true ) - dédupliquez et supprimez les branches de switch 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 ( 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êche les fonctions et variables de niveau supérieur spécifiques de la suppression unused (peut être un tableau, séparé par des virgules, RegExp ou une fonction. Implique un niveau toplevel )

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

  • unsafe (par défaut: false ) - appliquer les transformations "unsafe" (discussion ci-dessous)

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

  • unsafe_Function (par défaut: false ) - Compresser et mangle Function(args, code) lorsque les args et le code sont des chaînes littérales.

  • unsafe_math (par défaut: false ) - optimise les expressions numériques comme 2 * x * 3 en 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 ) - unsafe_regexp substitutions de variables avec des valeurs RegExp la même manière que s'il unsafe_regexp constantes.

  • unsafe_undefined (par défaut: false ) - remplacez void 0 s'il y a une variable nommée undefined 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 les variables non référencées (les affectations de variables directes simples ne comptent pas comme des références sauf si elles sont 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 Mangle

  • eval ( false par défaut) - Passez true aux noms mangle visibles dans les étendues où eval ou with sont utilisés.

  • keep_fnames (valeur par défaut false ) - Passez true pour ne pas modifier les noms de fonctions. Utile pour le code reposant sur Function.prototype.name . Voir aussi: l' option de compression keep_fnames .

  • reserved (default [] ) - Passe un tableau d'identificateurs qui doivent être exclus de la manipulation. Exemple: ["foo", "bar"] .

  • toplevel ( false par défaut) - Passez true 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 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 ) - Utilisez true pour permettre la modification des propriétés intégrées du DOM. Il n'est pas recommandé de remplacer ce paramètre.

  • debug (par défaut: false ) -— Mangle des 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 ) - Passez un littéral RegExp pour ne modifier que les noms de propriété correspondant à l'expression régulière.

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

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 --beautify , transmettez --beautify ( -b ). Vous pouvez éventuellement transmettre des arguments supplémentaires qui contrôlent la sortie du code:

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

  • beautify ( true par défaut) - s'il faut réellement embellir la sortie. Passer -b le définira sur true, mais vous devrez peut-être passer -b même si vous souhaitez générer du code minifié, afin de spécifier des arguments supplémentaires, afin que vous puissiez utilisez -b beautify=false pour le remplacer.

  • braces ( false par défaut) - insérez toujours des accolades dans les instructions if , for , do , while ou with , même si leur corps est une seule instruction.

  • comments (par défaut false ) - passez true 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 ( 4 par défaut)

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

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

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

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

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

  • preserve_line ( false par défaut) - transmettez true pour conserver les lignes, mais cela ne fonctionne que si beautify est défini sur false .

  • quote_keys ( false par défaut) - passe true pour citer toutes les clés dans les objets littéraux

  • quote_style ( 0 par défaut) - style de guillemet préféré pour les chaînes (affecte également les noms de propriété 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. 0 est le meilleur pour la taille gzip.
    • 1 - utilisez toujours des guillemets simples
    • 2 - utilisez toujours des guillemets doubles
    • 3 - utilisez toujours les citations originales
  • semicolons ( true par défaut) - instructions séparées par des points-virgules. Si vous passez false nous utiliserons dans la mesure du possible 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 sera insignifiante ).

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

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

  • width (par défaut 80 ) - prend effet uniquement lorsque l'embellissement est activé, cela spécifie une largeur de ligne (d'orientation) à laquelle l'embellisseur essaiera d'obéir. Cela fait référence à la largeur du texte de la ligne (hors retrait). Cela ne fonctionne pas très bien actuellement, mais cela rend le code généré par UglifyJS plus lisible.

  • wrap_iife ( false par défaut) - passe true pour envelopper les expressions de fonction immédiatement appelées. Voir # 640 pour plus de détails

Divers

PEUT passer par vous --comments . La conservation Certain aux commentaires La sortie Par défaut dans le style informatique conservera JSDoc contenant les commentaires "@preserve", "@license" ou "@cc_on" (compilation conditionnelle pour IE) Pass by You CAN. --comments all pour garder tous les commentaires, ou une expression régulière JavaScript valide pour ne conserver que 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 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'option de compress unsafe

Cela permet certaines transformations qui peuvent interrompre 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) ou Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp) ou exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...) → nous rejetons le new

Conditional compilation

Vous pouvez utiliser le --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 de 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 --define env.DEBUG=false .

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

Une autre façon de procéder consiste à déclarer vos globals en tant que constantes dans un fichier séparé et à les inclure dans la construction. Par exemple, vous pouvez avoir un fichier build/defines.js avec les éléments suivants:

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

et construisez votre code comme ceci:

1
uglifyjs 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 déclarations const si vous les utilisez. Si vous ciblez des environnements <ES6 qui ne prend pas en charge const , l'utilisation de var avec reduce_vars (activée 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_defs et 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 non constante arbitraire, il est nécessaire de préfixer la clé global_defs avec "@" pour demander à UglifyJS d'analyser la valeur comme une 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 une chaîne littérale:

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

Utilisation d'Uglify AST minify() 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 transformation et la transformation de l'AST natif peuvent être effectuées respectivement via TreeWalker et TreeTransformer .

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.Toutefois, UglifyJS a maintenant un convertisseur qui peut importer un SpiderMonkey AST.

Par exemple, Acorn est un analyseur ultra-rapide qui produit un SpiderMonkey AST. Il dispose d'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'option -p spidermonkey 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'option -p acorn qui utilisera Acorn pour faire tout l'analyse.Si vous passez cette option, UglifyJS aura require("acorn") .

Acorn est vraiment rapide (par exemple, 250 ms au lieu de 380 ms sur un code 650K), mais la conversion de l'arbre SpiderMonkey produit par Acorn prend encore 150 ms, 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 taille du code minifié pour la plupart des transformations de code JavaScript non élaborées. On peut simplement désactiver la compress pour accélérer les compilations Uglify de 3 à 4 fois. mangle -only mode Uglify a des vitesses de minification et des tailles de gzip comparables à celles du butternut :

d3.js réduire la taille taille gzip Minify time (secondes)
original 451 131 108 733 -
uglify-js@3.0.24 mangle = false, compresser = false 316 600 85 245 0,70
uglify-js@3.0.24 mangle = true, compresser = 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 minification rapide à partir de la CLI, utilisez:

1
uglifyjs file.js -m

Pour activer le mode de réduction rapide avec l'API, utilisez:

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

Cartes sources et débogage

On sait que diverses transformations de compress qui simplifient, réorganisent, incorporent et suppriment le code ont un effet négatif sur le débogage avec les mappages source. Cela est attendu car le code est optimisé et les mappages ne sont souvent tout simplement pas possibles car certains codes n'existent plus. le débogage de la carte source désactive l'option de compress 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 et Infinity n'ont pas été redéfinis en externe.
  • arguments.callee , arguments.caller et Function.prototype.caller ne sont pas utilisés.
  • Le code ne s'attend pas à ce que le contenu de Function.prototype.toString() ou Error.prototype.stack soit 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 ).
  • Object properties can be added , supprimées et modifiées (ce n'est pas empêché avec Object.defineProperty() , Object.defineProperties() , Object.freeze() , Object.preventExtensions() ou Object.seal() ).