Module communautaire génial

UglifyJS 3

UglifyJS est un outil d'analyse, d'analyse, de compression et d'embellissement 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 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 en utilisant des 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 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 passer d'abord les fichiers d'entrée, puis de passer 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 étendue globale, c'est-à-dire une référence d'un fichier à une variable / fonction déclarée dans un autre fichier sera correctement mise 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 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 mappage source, ce qui est très utile pour déboguer votre code JavaScript compressé. Pour obtenir un mappage source, passez --source-map --output output.js (le mappage source sera écrit dans output.js.map ) .

Options additionelles:

  • --source-map "filename='<NAME>'" pour spécifier le nom de la carte source.

  • --source-map "root='<URL>'" pour passer 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 file1.js et file2.js , supprimera la sortie dans foo.min.js et la carte source dans foo.min.js.map . La cartographie source fera référence à http://foo.com/src/js/file1.js et http://foo.com/src/js/file2.js (en fait, il répertoriera 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é généré par un compilateur tel que CoffeeScript, le mappage au code JS ne sera pas très utile. Au lieu de cela, vous souhaitez mapper à nouveau le code d'origine (par exemple CoffeeScript). UglifyJS a un en supposant que vous disposez d'un mappage à partir de CoffeeScript → JS compilé, UglifyJS peut générer une mappe à 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 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 mangle CLI

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

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

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

Lorsque la modification est activée mais que vous souhaitez empêcher certains noms d'être modifié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 le require , les exports et les noms $ ne soient modifiés.

CLI manipulant les noms de propriété ( --mangle-props )

Remarque: CECI BRISERA PROBABLEMENT VOTRE CODE. La gestion des noms de propriété est une étape distincte, différente de la gestion des noms de variable. Passez --mangle-props pour l'activer. Elle gommera 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 dans les 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());

Combiner les options de propriétés 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 pour 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 fonction.

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

Lorsque vous compressez plusieurs fichiers à l'aide de cette option, afin qu'ils fonctionnent ensemble à la fin, nous devons nous assurer d'une manière ou d'une autre qu'une propriété est modifiée avec 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 et part2.js seront cohérents entre eux en termes de noms de propriété mutilés.

L'utilisation du cache de noms n'est pas nécessaire si vous compressez tous vos fichiers en un seul appel à UglifyJS.

Gérer les 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 la propriété ( foo ) afin qu'il ne soit pas modifié dans tout le script même lorsqu'il est utilisé dans un style sans 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é sans les o.foo complètement. Par exemple, la propriété o.foo se o.foo en o._$foo$_ avec cette option. Cela permet de gérer les propriétés d'une grande base de code tout en étant en mesure de déboguer le code et d'identifier où les mutilations cassent 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 passer un suffixe personnalisé en utilisant --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é modifiée Une technique consiste à transmettre un nombre aléatoire à chaque compilation pour simuler le changement de mangling 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 les erreurs telles que l'écriture de clés déformées dans le stockage.

Référence API

En supposant une 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 exécutera toutes les phases de minification de manière configurable. Par défaut, minify() les options de compress et de 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 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 d'une 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 (default false ) - passez true pour 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 (par défaut {} ) - passez false pour ignorer complètement la compression. Passez un objet pour spécifier des options de compression personnalisées.

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

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

  • toplevel (valeur par défaut false ) toplevel true si vous souhaitez activer la variable de niveau supérieur et le changement de nom de fonction et supprimer les variables et fonctions inutilisées.

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

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

  • keep_fnames (par défaut: false ) -pass true pour empêcher la suppression ou la modification des noms de fonction. 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 le mappage source n'est pas enregistré dans un fichier, il est simplement renvoyé 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 est uniquement utilisé 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 pour ê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 code 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 l'en X-SourceMap tête X-SourceMap place, vous pouvez simplement omettre sourceMap.url .

Options d'analyse

  • bare_returns (default false ) - supporte les instructions de return niveau supérieur

  • html5_comments (par défaut true )

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

Options de compression

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

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

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

  • drop_console (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 pure_funcs appel de fonction, utilisez alors pure_funcs au lieu.

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

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

  • expression (par défaut: false ) - Passez true pour conserver les valeurs d'achèvement des instructions de terminal sans return , par exemple dans les bookmarklets.

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

  • hoist_funs (défaut: false ) - déclarations de la fonction hoist

  • hoist_props (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 de compress passes définie sur 2 ou plus, et l'option de compress toplevel activée.

  • hoist_vars (default: false ) - déclarations var hoist_vars (c'est false par défaut car cela semble augmenter la taille de la sortie en général)

  • if_return (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 (défaut: true ) - joint des instructions var consécutives

  • keep_fargs (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 (défaut: false ) - Passez true pour empêcher le compresseur de rejeter les noms de fonction. Utile pour le code reposant sur Function.prototype.name . Voir aussi: l' option keep_fnames mangle .

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

  • loops (par défaut: true ) - optimisations pour do , while et for boucles lorsque nous pouvons déterminer statiquement la condition.

  • negate_iife (par défaut: true ) - annuler "les expressions de fonction appelées immédiatement" où la valeur de retour est ignorée, pour éviter les parens que le générateur de code insérerait.

  • passes (par défaut: 1 ) - Le nombre maximal d'exécutions de compresser. Dans certains cas, plus d'une passe conduit à un code compressé supplémentaire. 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 (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 conservera toujours Math.floor(a/b) , sans savoir ce qu'elle 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 serait 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 les mutilations.

  • pure_getters (défaut: "strict" ) - Si vous passez true pour cela, UglifyJS supposera que l'accès à la propriété 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 non null ou undefined .

  • reduce_funcs (par défaut: true ) - Permet aux fonctions à usage unique d'être mises en ligne 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 la reduce_vars de reduce_vars activée. N'affecte pas négativement les autres principaux navigateurs.

  • reduce_vars (par défaut: true ) - Améliore l'optimisation des variables attribuées avec et utilisées comme valeurs constantes.

  • sequences (par défaut: true ) - joindre 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 de sequences par défaut est 200 Définissez l'option sur false ou 0 pour la désactiver. La plus petite longueur de sequences est 2 Une valeur de sequences de 1 est protégée pour être équivalente à true et en tant que telle signifie 200 En de rares occasions, la limite de séquence par défaut conduit à 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 supprimées 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 la Par exemple: /*@__PURE__*/foo();

  • switches (par défaut: true ) - de-dupliquer et supprimer les branches de switch inaccessibles

  • toplevel (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 les fonctions et variables non référencées)

  • top_retain (défaut: null ) - empêche la suppression unused 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 un niveau toplevel )

  • typeofs (par défaut: true ) - Transforme typeof foo == "undefined" en foo === void 0 Remarque: recommandez 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 des transformations "dangereuses" (discussion ci-dessous)

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

  • unsafe_Function (défaut: false ) - Function(args, code) compress et mangle Function(args, code) lorsque les args et le code sont des littéraux de chaîne.

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

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

  • unsafe_regexp (défaut: false ) - unsafe_regexp substitutions de variables avec des valeurs RegExp la même manière que si elles étaient constantes.

  • unsafe_undefined (défaut: false ) - remplacez void 0 s'il existe une variable nommée undefined dans la portée (le nom de la variable sera modifié, 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 directes de variables simples ne comptent pas comme références sauf si elles sont définies sur "keep_assign" )

  • warnings (default: 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 de mangle visibles dans les étendues où eval ou with sont utilisés.

  • keep_fnames (default false ) - Passez true pour ne pas modifier les noms de fonction. Utile pour le code reposant sur Function.prototype.name . Voir aussi: l' option compresser keep_fnames .

  • reserved (par défaut [] ) - Passez un tableau d'identifiants qui devraient être exclus de la manipulation. Exemple: ["foo", "bar"] .

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

  • debug (défaut: false ) -— Mangle 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 (défaut: false ) -— Ne modifie que les noms de propriété non cotés.

  • 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 sortir le code le plus court possible par défaut. Dans le cas où vous souhaitez embellir la sortie, passez --beautify ( -b ). Vous pouvez éventuellement passer 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 rationnelles (affecte les directives avec des caractères non ascii devenant invalides)

  • beautify (valeur par défaut true ) - pour embellir réellement la sortie. Passer -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 utilisez -b beautify=false pour le remplacer.

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

  • comments (default 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 (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 les commentaires HTML et la barre oblique dans les occurrences de </script> dans les chaînes

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

  • max_line_len (default false ) - longueur de ligne maximale (pour le code uglified)

  • preamble (valeur par défaut null ) - une fois transmis, il doit s'agir d'une chaîne et il sera ajouté au début littéralement. 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 (default false ) - passez true pour conserver les lignes, mais cela ne fonctionne que si beautify est défini sur false .

  • quote_keys (default false ) - passez true pour 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é 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 préférable pour la taille gzip.
    • 1 - utilisez toujours des guillemets simples
    • 2 - utilisez toujours des guillemets doubles
    • 3 - utilisez toujours les citations originales
  • semicolons (valeur par défaut true ) - séparez les instructions par des points-virgules. Si vous passez false mesure du possible, nous utiliserons une nouvelle ligne au lieu d'un point-virgule, ce qui conduira à une sortie plus lisible du code uglified (la taille avant gzip pourrait être plus petite; la taille après gzip ne sera pas significativement plus grande ).

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

  • webkit ( false par défaut) - 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. Il fait référence à la largeur du texte de la ligne (à l'exclusion du 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) - passez true pour envelopper les expressions de fonction immédiatement appelées. Voir # 640 pour plus de détails.

Divers

CAN Pass by You --comments . La conservation de certains commentaires La sortie Par défaut dans le style informatique gardera JSDoc qui contient des commentaires "@preserve", "@license" ou "@cc_on" (Compilation conditionnelle pour IE) Passez par vous CAN. --comments all to keep all the comments, or a valid JavaScript regexp to keep only comments that match this regexp. For example --comments /^!/ will keep comments like /*! Copyright Notice */ .

Note, however, that there might be situations where comments are lost. For example:

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

Even though it has "@preserve", the comment will be lost because the inner function g (which is the AST node to which the comment is attached to) is discarded by the compressor as not referenced.

The safest comments where to place copyright information (or other info that needs to be kept in the output) are comments attached to toplevel nodes.

The unsafe compress option

It enables some transformations that might break code logic in certain contrived cases, but should be fine for most code. You might want to try it on your own code, it should reduce the minified size. Here's what happens when this flag is on:

  • new Array(1, 2, 3) or Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp) or exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...) → we discard the new

Conditional compilation

You can use the --define ( -d ) switch in order to declare global variables that UglifyJS will assume to be constants (unless defined in scope). For example if you pass --define DEBUG=false then, coupled with dead code removal UglifyJS will discard the following from the output:

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

You can specify nested constants in the form of --define env.DEBUG=false .

UglifyJS will warn about the condition being always false and about dropping unreachable code; for now there is no option to turn off only this specific warning, you can pass warnings=false to turn off all warnings.

Another way of doing that is to declare your globals as constants in a separate file and include it into the build. For example you can have a build/defines.js file with the following:

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

and build your code like this:

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

UglifyJS will notice the constants and, since they cannot be altered, it will evaluate references to them to the value itself and drop unreachable code as usual. The build will contain the const declarations if you use them. If you are targeting < ES6 environments which does not support const , using var with reduce_vars (enabled by default) should suffice.

Conditional compilation API

You can also use conditional compilation via the programmatic API. With the difference that the property name is global_defs and is a compressor property:

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

To replace an identifier with an arbitrary non-constant expression it is necessary to prefix the global_defs key with "@" to instruct UglifyJS to parse the value as an expression:

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

Otherwise it would be replaced as string literal:

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

Using native Uglify AST with 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

Transversal and transformation of the native AST can be performed through TreeWalker and TreeTransformer respectively.

ESTree / SpiderMonkey AST

UglifyJS has its own abstract syntax tree format; for practical reasons we can't easily change to using the SpiderMonkey AST internally. However, UglifyJS now has a converter which can import a SpiderMonkey AST.

For example Acorn is a super-fast parser that produces a SpiderMonkey AST. It has a small CLI utility that parses one file and dumps the AST in JSON on the standard output. To use UglifyJS to mangle and compress that:

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

The -p spidermonkey option tells UglifyJS that all input files are not JavaScript, but JS code described in SpiderMonkey AST in JSON. Therefore we don't use our own parser in this case, but just transform that AST into our internal AST.

Use Acorn for parsing

More for fun, I added the -p acorn option which will use Acorn to do all the parsing. If you pass this option, UglifyJS will require("acorn") .

Acorn is really fast (eg 250ms instead of 380ms on some 650K code), but converting the SpiderMonkey tree that Acorn produces takes another 150ms so in total it's a bit more than just using UglifyJS's own parser.

Uglify Fast Minify Mode

It's not well known, but whitespace removal and symbol mangling accounts for 95% of the size reduction in minified code for most JavaScript - not elaborate code transforms. One can simply disable compress to speed up Uglify builds by 3 to 4 times. In this fast mangle -only mode Uglify has comparable minify speeds and gzip sizes to butternut :

d3.js minify size gzip size minify time (seconds)
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

To enable fast minify mode from the CLI use:

1
uglifyjs file.js -m

To enable fast minify mode with the API use:

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

Source maps and debugging

Various compress transforms that simplify, rearrange, inline and remove code are known to have an adverse effect on debugging with source maps. This is expected as code is optimized and mappings are often simply not possible as some code no longer exists. For highest fidelity in source map debugging disable the Uglify compress option and just use mangle .

Compiler assumptions

To allow for better optimizations, the compiler makes various assumptions:

  • .toString() and .valueOf() don't have side effects, and for built-in objects they have not been overridden.
  • undefined , NaN and Infinity have not been externally redefined.
  • arguments.callee , arguments.caller and Function.prototype.caller are not used.
  • The code doesn't expect the contents of Function.prototype.toString() or Error.prototype.stack to be anything in particular.
  • Getting and setting properties on a plain object does not cause other side effects (using .watch() or Proxy ).
  • Object properties can be added , removed and modified (not prevented with Object.defineProperty() , Object.defineProperties() , Object.freeze() , Object.preventExtensions() or Object.seal() ).