Потрясающий модуль сообщества

УглифайДжС 3

UglifyJS — это набор инструментов для парсера, минификатора, сжатия и улучшения JavaScript JavaScript.

Примечание:

  • uglify-js@3имеет упрощенный API и CLI , который не имеет обратной совместимости сuglify-js@2 .
  • Документацию к 2.xрелизам UglifyJS можно найти здесь .
  • uglify-jsподдерживает только JavaScript (ECMAScript 5).
  • Чтобы минимизировать ECMAScript 2015 или более позднюю версию, выполните транспиляцию с помощью таких инструментов, как Babel .

Установить

Сначала убедитесь, что у вас установлена ​​последняя версия node.js (после этого шага вам может потребоваться перезагрузить компьютер).

Из NPM для использования в качестве приложения командной строки:

1
npm install uglify-js -g

Из NPM для программного использования:

1
npm install uglify-js

Использование командной строки

1
uglifyjs [input files] [options]

UglifyJS может принимать несколько входных файлов. Рекомендуется сначала передать входные файлы, а затем параметры. UglifyJS последовательно анализирует входные файлы и применяет любые параметры сжатия. Файлы анализируются в одной глобальной области, то есть по ссылке из файла в некоторую переменную/функцию, объявленную в другом файле, будет правильно сопоставляться.

Если входной файл не указан, UglifyJS будет читать из STDIN.

Если вы хотите передать параметры перед входными файлами, разделите их двойным тире, чтобы предотвратить использование входных файлов в качестве аргументов параметров:

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.

Укажите --output( -o), чтобы объявить выходной файл. В противном случае выходные данные перейдут в STDOUT.

Параметры исходной карты CLI

UglifyJS может генерировать файл исходной карты, что очень полезно для отладки сжатого JavaScript. Чтобы получить исходную карту, передайте --source-map --output output.js(исходная карта будет записана в output.js.map).

Дополнительные опции:

  • --source-map "filename='<NAME>'"чтобы указать имя исходной карты.

  • --source-map "root='<URL>'"чтобы передать URL-адрес, по которому можно найти исходные файлы.

  • --source-map "url='<URL>'"чтобы указать URL-адрес, по которому можно найти исходную карту. В противном случае UglifyJS предполагает, X-SourceMapчто используется HTTP, и пропустит //# sourceMappingURL=директиву.

Например:

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

Вышеупомянутое сжимает и искажает file1.jsи file2.js, выводит выходные данные foo.min.jsи исходную карту в foo.min.js.map. Сопоставление источника будет ссылаться на http://foo.com/src/js/file1.jsи http://foo.com/src/js/file2.js(на самом деле оно будет указано http://foo.com/src как корень исходной карты, а исходные файлы - как js/file1.jsи js/file2.js).

Composed source map

Когда вы сжимаете код JS, который был выведен таким компилятором, как CoffeeScript, сопоставление с кодом JS не будет слишком полезным. Вместо этого вам нужно сопоставить обратно исходный код (т. е. CoffeeScript). UglifyJS имеет Если у вас есть сопоставление CoffeeScript → скомпилированный JS, UglifyJS может сгенерировать карту из CoffeeScript → сжатый JS, сопоставляя каждый токен в скомпилированном JS с его исходным местоположением.

Чтобы использовать эту функцию, необходимо пройти --source-map "content='/path/to/input/source.map'" или --source-map "content=inline"если исходная карта включена в исходные коды.

Параметры сжатия CLI

Вам необходимо передать --compress( -c), чтобы включить компрессор. При желании вы можете передать список параметров сжатия , разделенных запятыми .

Параметры имеют форму foo=bar, или просто foo(последний подразумевает логический параметр, который вы хотите установить true; по сути, это ярлык для foo=true).

Пример:

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

Параметры управления CLI

Чтобы включить манглер, вам необходимо передать --mangle( -m). Поддерживаются следующие параметры (через запятую):

  • toplevel(по умолчанию false) — искажать имена, объявленные в области верхнего уровня.

  • eval(по умолчанию false) — имена искажений видны в областях, где используются evalили .with

Если искажение включено, но вы хотите предотвратить искажение определенных имен, вы можете объявить эти имена с помощью --mangle reserved— передать список имен, разделенных запятыми. Например:

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

чтобы предотвратить изменение имен requireи exports.$

CLI искажает имена свойств ( --mangle-props)

Примечание. ЭТО ВЕРОЯТНО НАРУШИТ ВАШ КОД. Изменение имен свойств — это отдельный шаг, отличный от изменения имен переменных. Нажмите, --mangle-propsчтобы включить его. Это приведет к искажению всех свойств во входном коде, за исключением встроенных свойств DOM и свойств в ядре JavaScript. занятия. Например:

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

Исказить все свойства (кроме 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());

Исказить все свойства, кроме 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._());

Исказить все свойства, соответствующие 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());

Комбинирование параметров свойств 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());

Чтобы это было полезно, мы избегаем искажения стандартных имен JS по умолчанию ( --mangle-props builtinsдля переопределения).

Предоставляется файл исключений по умолчанию, tools/domprops.jsonкоторый должен охватывать большинство стандартных свойств JS и DOM, определенных в различных браузерах. Нажмите, --mangle-props dompropsчтобы отключить эту функцию.

Регулярное выражение можно использовать для определения того, какие имена свойств следует искажать. Например, --mangle-props regex=/^_/будут искажаться только те имена свойств, которые начинаются с подчеркивания.

Когда вы сжимаете несколько файлов с помощью этой опции, чтобы они в конечном итоге работали вместе, нам нужно каким-то образом гарантировать, что одно свойство будет преобразовано в одно и то же имя во всех них. Для этого pass --name-cache filename.json и UglifyJS будет поддерживать эти сопоставления в виде файл, который затем можно использовать повторно. Изначально он должен быть пустым. Пример:

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

Теперь part1.jsи part2.jsбудут согласовываться друг с другом с точки зрения искаженных имен свойств.

Использование кэша имен не требуется, если вы сжимаете все файлы за один вызов UglifyJS.

Искажение имен без кавычек ( --mangle-props keep_quoted)

Использование имени свойства в кавычках ( o["foo"]) резервирует имя свойства ( foo), чтобы оно не искажалось во всем сценарии, даже если оно используется в стиле без кавычек ( o.foo).

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

Вы также можете передать --mangle-props debug, чтобы искажать имена свойств, не скрывая их полностью. Например, с помощью этой опции свойство o.foo будет искажаться o._$foo$_. Это позволяет искажать свойства большой базы кода, сохраняя при этом возможность отлаживать код и определять, где искажение что-то нарушает.

1
$ uglifyjs stuff.js --mangle-props debug -c -m
1
var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);

Вы также можете передать собственный суффикс, используя --mangle-props debug=XYZ. Затем он будет преобразован o.fooв o._$foo$XYZ_. Вы можете менять его каждый раз при компиляции скрипта, чтобы определить, как было искажено свойство. Один из методов заключается в передаче случайного числа при каждой компиляции для имитации изменения искажения с различными входные данные (например, при обновлении входного сценария новыми свойствами), а также для выявления ошибок, таких как запись искаженных ключей в хранилище.

Справочник по API

Предполагая установку через NPM, вы можете загрузить UglifyJS в свое приложение следующим образом:

1
var UglifyJS = require("uglify-js");

Существует одна функция высокого уровня, minify(code, options)которая будет выполнять все этапы минимизации настраиваемым образом. По умолчанию minify()включены параметры compress и mangle. Пример:

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}

Вы можете minifyиспользовать более одного файла JavaScript одновременно, используя объект в качестве первого аргумента, где ключи — это имена файлов, а значения — исходный код:

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

Опция 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);

Опция 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));

Вы можете сохранить кэш имен в файловой системе следующим образом:

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

Пример комбинации вариантов 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);"

Для создания предупреждений:

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}

Пример ошибки:

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}

Примечание: в отличие от uglify-js@2.x, 3.xAPI не выдает ошибок.Для достижения аналогичного эффекта можно сделать следующее:

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

Минимизировать параметры

  • warnings(по умолчанию false) — переход trueдля возврата предупреждений компрессора в result.warnings. Используйте значение "verbose"для более подробных предупреждений.

  • parse(по умолчанию {}) — передайте объект, если вы хотите указать некоторые дополнительные параметры анализа .

  • compress(по умолчанию {}) — перейдите false, чтобы полностью пропустить сжатие. Передайте объект, чтобы указать пользовательские параметры сжатия .

  • mangle(по умолчанию true) — передать false, чтобы пропустить искажение имен, или передать объект, чтобы указать параметры искажения (см. ниже).

    • mangle.properties(по умолчанию false) — подкатегория параметра mangle. Передайте объект, чтобы указать пользовательские параметры свойства mangle .
  • output(по умолчанию null) — передайте объект, если вы хотите указать дополнительные параметры вывода . Значения по умолчанию оптимизированы для наилучшего сжатия.

  • sourceMap(по умолчанию false) — передайте объект, если вы хотите указать параметры исходной карты .

  • toplevel(по умолчанию false) — установите, trueесли вы хотите включить изменение имен переменных и функций верхнего уровня и удалить неиспользуемые переменные и функции.

  • nameCache(по умолчанию null) — передать пустой объект {}или ранее использованный nameCacheобъект, если вы хотите кэшировать искаженные имена переменных и свойств при нескольких вызовах minify(). Примечание: это свойство доступно для чтения и записи. minify()Прочитает состояние кэша имен этого объекта и обновит его. во время минимизации, чтобы пользователь мог повторно использовать или сохранять его извне.

  • ie8(по умолчанию false) — настроена trueподдержка IE8.

  • keep_fnames(по умолчанию: false) — передать true, чтобы предотвратить отбрасывание или искажение имен функций.Полезно для кода, использующего Function.prototype.name.

Минимизировать структуру параметров

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

Чтобы создать исходную карту:

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

Обратите внимание, что исходная карта не сохраняется в файле, она просто возвращается в формате result.map. Переданное значение sourceMap.urlиспользуется только для установки //# sourceMappingURL=out.js.mapв result.code. Значение filenameиспользуется только для установки fileатрибута (см. спецификацию ) в файле исходной карты.

Вы можете установить опцию sourceMap.urlbe "inline", и исходная карта будет добавлена ​​к коду.

Вы также можете указать свойство sourceRoot для включения в исходную карту:

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

Если вы сжимаете скомпилированный JavaScript и у вас есть карта исходного кода, вы можете использовать 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`

Если вместо этого вы используете X-SourceMapзаголовок, вы можете просто опустить sourceMap.url.

Параметры разбора

  • bare_returns(по умолчанию ) — поддержка операторов falseверхнего уровняreturn

  • html5_comments(по умолчанию true)

  • shebang(по умолчанию true) — поддержка #!commandв качестве первой строки

Параметры сжатия

  • arguments(по умолчанию: true) — arguments[index]по возможности замените именем параметра функции.

  • booleans(по умолчанию: true) — различные оптимизации для логического контекста, например!!a ? b : c → a ? b : c

  • collapse_vars(по умолчанию: true) — Свернуть одноразовые непостоянные переменные, если допускаются побочные эффекты.

  • comparisons(по умолчанию: true) — применить определенные оптимизации к двоичным узлам, например !(a <= b) → a > b, попытки инвертировать двоичные узлы, например a = !b && !c && !d && !e → a=!(b||c||d||e)и т. д.

  • conditionals(по умолчанию: true) — применить оптимизацию для if-s и условных выражений

  • dead_code(по умолчанию: true) — удалить недоступный код

  • drop_console(по умолчанию: false) — Pass trueдля отмены вызовов console.*функций. Если вы хотите удалить конкретный вызов функции, например, console.infoи/или сохранить побочные эффекты от аргументов функции после удаления вызова функции, используйте pure_funcsвместо этого.

  • drop_debugger(по умолчанию: true) — удалить debugger;операторы

  • evaluate(по умолчанию: true) — попытка вычислить константные выражения

  • expression(по умолчанию: false) — передать true, чтобы сохранить значения завершения из операторов терминала без return, например, в букмарклетах.

  • global_defs(по умолчанию: {}) — см. условную компиляцию

  • hoist_funs(по умолчанию: false) — объявления функций подъема

  • hoist_props(по умолчанию: true) — перенос свойств из константного объекта и литералов массива в обычные переменные с учетом набора ограничений. Например: var o={p:1, q:2}; f(o.p, o.q);преобразуется в f(1, 2);. Примечание: hoist_props лучше всего работает, если mangleпараметр включен, compressпараметр passesустановлен на 2значение или выше, а compressпараметр toplevelвключен.

  • hoist_vars(по умолчанию: false) — varобъявления подъема (это false по умолчанию, потому что кажется, что это увеличивает размер вывода в целом)

  • if_return(по умолчанию: true) — оптимизация для if/return и if/continue

  • inline(по умолчанию: true) — встроенные вызовы функции с помощью returnоператора simple/:

    • false--такой же как0
    • 0-- отключена встраивание
    • 1-- встроенные простые функции
    • 2-- встроенные функции с аргументами
    • 3-- встроенные функции с аргументами и переменными
    • true--такой же как3
  • join_vars(по умолчанию: true) — объединить последовательные varоператоры

  • keep_fargs(по умолчанию: true) — не позволяет компрессору отбрасывать неиспользуемые аргументы функции. Это необходимо для кода, который использует Function.length.

  • keep_fnames(по умолчанию: false) -- Пропустите true, чтобы компрессор не отбрасывал имена функций. Полезно для кода, использующего Function.prototype.name. См. также: keep_fnames опция mangle .

  • keep_infinity(по умолчанию: false) — используйте trueдля предотвращения Infinityсжатия в 1/0, что может вызвать проблемы с производительностью в Chrome.

  • loops(по умолчанию: true) — оптимизация для и циклов do, когда мы можем статически определить условие.whilefor

  • negate_iife(по умолчанию: true) — отрицание «выражений с немедленным вызовом функций», при которых возвращаемое значение отбрасывается, чтобы избежать круглых скобок, которые вставляет генератор кода.

  • passes(по умолчанию: 1) — максимальное количество раз запуска сжатия. В некоторых случаях более одного прохода приводит к дальнейшему сжатию кода. Имейте в виду, что большее количество проходов займет больше времени.

  • properties(по умолчанию: true) — переписать доступ к свойству, используя, например, запись через точку.foo["bar"] → foo.bar

  • pure_funcs(по умолчанию: null) -- Вы можете передать массив имен, и UglifyJS предположит, что эти функции не производят побочных эффектов. ОПАСНОСТЬ: не будет проверять, переопределено ли имя в области видимости. Пример случая здесь, например. var q = Math.floor(a/b)Если переменная qравна не используется где-либо еще, UglifyJS удалит его, но все равно сохранит Math.floor(a/b), не зная, что он делает. Вы можете передать, pure_funcs: [ 'Math.floor' ]чтобы сообщить ему, что эта функция не будет производить никакого побочного эффекта, и в этом случае весь оператор будет отброшен. текущая реализация добавляет некоторые накладные расходы (сжатие будет медленнее).Убедитесь, что символы ниже pure_funcs также находятся внизу mangle.reserved, чтобы избежать искажения.

  • pure_getters(по умолчанию: "strict") -- Если вы передадите trueэто, UglifyJS будет считать, что доступ к свойствам объекта (например, foo.barили foo["bar"]) не имеет каких-либо побочных эффектов. Укажите "strict", чтобы рассматриваться foo.barкак свободный от побочных эффектов только тогда, когда fooвы точно не выкинете, т.е. nullили undefined.

  • reduce_funcs(по умолчанию: true) — позволяет встраивать одноразовые функции в качестве функциональных выражений, когда это допустимо, обеспечивая дальнейшую оптимизацию. Включено по умолчанию. Параметр зависит от того, reduce_vars включен ли он. Некоторый код выполняется быстрее в движке Chrome V8, если этот параметр отключен. Не работает. негативно повлиять на другие основные браузеры.

  • reduce_vars(по умолчанию: true) — Улучшить оптимизацию переменных, которым назначены и используются как постоянные значения.

  • sequences(по умолчанию: true) — соединение последовательных простых операторов с помощью оператора запятой. Может быть установлено положительное целое число, чтобы указать максимальное количество последовательных последовательностей запятых, которые будут сгенерированы. Если этот параметр установлен, то предел trueпо умолчанию равен . Установить параметр или отключить. Наименьшая длина — . Значение считается эквивалентным и, как таковое, означает . В редких случаях ограничение последовательностей по умолчанию приводит к очень медленному времени сжатия, и в этом случае рекомендуется значение или меньше.sequences200false0sequences2sequences1true20020

  • side_effects(по умолчанию: true) — переход falseдля отключения потенциально удаляемых функций, помеченных как «чистые». Вызов функции помечается как «чистый», если аннотация комментария /*@__PURE__*/или /*#__PURE__*/непосредственно предшествует вызову. Например:/*@__PURE__*/foo();

  • switches(по умолчанию: true) — дедупликация и удаление недоступных switchветвей

  • toplevel(по умолчанию: false) — удалить неиспользуемые функции ( "funcs") и/или переменные ( "vars") в области верхнего уровня ( falseпо умолчанию, trueчтобы удалить как неиспользуемые функции, так и переменные)

  • top_retain(по умолчанию: null) — предотвращает удаление определенных функций и переменных верхнего уровня unused(может быть массивом, через запятую, RegExp или function. Implises toplevel)

  • typeofs(по умолчанию: true) — Преобразуется typeof foo == "undefined"в foo === void 0Примечание: рекомендуется установить это значение falseдля IE10 и более ранних версий из-за известных проблем.

  • unsafe(по умолчанию: false) — применить «небезопасные» преобразования (обсуждение ниже)

  • unsafe_comps(по умолчанию: false) — сжимает выражения, например, a <= bпредполагая, что ни один из операндов не может быть (приведен к) NaN.

  • unsafe_Function(по умолчанию: false) — сжимает и изменяет, Function(args, code) если оба argsи codeявляются строковыми литералами.

  • unsafe_math(по умолчанию: false) — оптимизирует числовые выражения, такие как 2 * x * 3in 6 * x, которые могут давать неточные результаты с плавающей запятой.

  • unsafe_proto(по умолчанию: false) — оптимизирует выражения, например Array.prototype.slice.call(a), в[].slice.call(a)

  • unsafe_regexp(по умолчанию: false) — разрешить замену переменных значениями RegExpтак же, как если бы они были константами.

  • unsafe_undefined(по умолчанию: false) — заменяет, void 0если в области видимости есть переменная с именем undefined(имя переменной будет искажено, обычно сокращается до одного символа)

  • unused(по умолчанию: true) — удалить неиспользуемые функции и переменные (простые прямые назначения переменных не считаются ссылками, если не установлено значение "keep_assign")

  • warnings(по умолчанию: false) — отображать предупреждения при удалении недостижимого кода или неиспользуемых объявлений и т. д.

Параметры искажения

  • eval(по умолчанию false) — переход trueк именам искажений, видимым в областях, где используются evalили .with

  • keep_fnames(по умолчанию false) — передать true, чтобы не искажать имена функций.Полезно для кода, использующего .См Function.prototype.name. также: keep_fnames опция сжатия .

  • reserved(по умолчанию []) — передать массив идентификаторов, которые следует исключить из искажения. Пример: ["foo", "bar"].

  • toplevel(по умолчанию false) — переход trueк именам преобразования, объявленным в области верхнего уровня.

Примеры:

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(по умолчанию: false) — используйте true, чтобы разрешить изменение встроенных свойств DOM. Не рекомендуется переопределять этот параметр.

  • debug(по умолчанию: false) -- Искажать имена, при этом исходное имя все еще присутствует. Передайте пустую строку, ""чтобы включить, или непустую строку, чтобы установить суффикс отладки.

  • keep_quoted(по умолчанию: false) — Искажать только имена свойств без кавычек.

  • regex(по умолчанию: null) — Передайте литерал RegExp, чтобы изменить только имена свойств, соответствующие регулярному выражению.

  • reserved(по умолчанию: []) — Не искажать имена свойств, перечисленные в reservedмассиве.

Варианты вывода

По умолчанию генератор кода пытается вывести как можно более короткий код. Если вы хотите улучшить вывод, передайте --beautify( -b). При желании вы можете передать дополнительные аргументы, управляющие выводом кода:

  • ascii_only(по умолчанию false) — экранирование символов Юникода в строках и регулярных выражениях (влияет на директивы, в которых символы, отличные от ascii, становятся недействительными)

  • beautify(по умолчанию true) — нужно ли на самом деле украшать вывод. При передаче -bдля этого параметра будет установлено значение true, но вам может потребоваться передать его, -bдаже если вы хотите сгенерировать минимизированный код, чтобы указать дополнительные аргументы, чтобы вы могли использовать -b beautify=falseего для переопределения.

  • braces(по умолчанию false) — всегда вставляйте фигурные скобки в операторы if, for, doили , даже если их тело whileпредставляет withсобой один оператор.

  • comments(по умолчанию false) — передать trueили "all"сохранить все комментарии, "some"сохранить некоторые комментарии, строку регулярного выражения (например /^!/) или функцию.

  • indent_level(по умолчанию 4)

  • indent_start(по умолчанию 0) — предварять все строки указанным количеством пробелов

  • inline_script(по умолчанию true) — экранирование HTML-комментариев и косой черты в </script>строках

  • keep_quoted_props(по умолчанию false) — при включении предотвращает удаление кавычек из имен свойств в литералах объектов.

  • max_line_len(по умолчанию false) — максимальная длина строки (для измененного кода)

  • preamble(по умолчанию null) – при передаче это должна быть строка, и она будет добавлена ​​к выходным данным буквально. Исходная карта будет адаптирована к этому тексту. Может использоваться, например, для вставки комментария, содержащего информацию о лицензии.

  • preserve_line(по умолчанию false) — переход trueдля сохранения строк, но это работает, только если beautifyустановлено значение false.

  • quote_keys(по умолчанию false) — передать trueв кавычки все ключи в литеральных объектах

  • quote_style(по умолчанию 0) — предпочтительный стиль кавычек для строк (также влияет на имена свойств и директивы в кавычках):

    • 0-- предпочитает двойные кавычки, переключается на одинарные кавычки, когда в самой строке больше двойных кавычек. 0Лучше всего подходит для размера gzip.
    • 1-- всегда используйте одинарные кавычки
    • 2-- всегда используйте двойные кавычки
    • 3-- всегда используйте оригинальные кавычки
  • semicolons(по умолчанию true) -- отдельные операторы с точкой с запятой. Если вы передадите, falseто, когда это возможно, мы будем использовать новую строку вместо точки с запятой, что приведет к более читаемому выводу искаженного кода (размер до gzip мог бы быть меньше; размер после gzip незначительно больше).

  • shebang(по умолчанию true) — сохранить шебанг #!в преамбуле (скрипты bash)

  • webkit(по умолчанию false) — включить обходные пути для ошибок WebKit.Пользователям PhantomJS следует установить для этой опции значение true.

  • width(по умолчанию 80) — действует только тогда, когда украшение включено. Это определяет (ориентирующую) ширину линии, которой будет пытаться соответствовать средство украшения. Это относится к ширине текста строки (исключая отступы). Это работает не очень хорошо. в настоящее время, но это делает код, сгенерированный UglifyJS, более читабельным.

  • wrap_iife(по умолчанию false) — переход trueк переносу немедленно вызываемых функциональных выражений. Подробнее см. #640 .

Разнообразный

Вы можете передать --comments, чтобы сохранить определенные комментарии в выходных данных. По умолчанию будут сохраняться комментарии в стиле JSDoc, содержащие "@preserve", "@license" или "@cc_on" (условная компиляция для IE). Вы можете передать, --comments allчтобы сохранить все комментарии или допустимое регулярное выражение JavaScript, чтобы сохранять только комментарии, соответствующие этому регулярному выражению. Например, --comments /^!/ будут сохраняться комментарии типа /*! Copyright Notice */.

Однако учтите, что могут возникнуть ситуации, когда комментарии теряются, например:

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

Несмотря на то, что у него есть «@preserve», комментарий будет потерян, поскольку внутренняя функция g(которая является узлом AST, к которому прикреплен комментарий) отбрасывается компрессором как не указанная.

Самые безопасные комментарии для размещения информации об авторских правах (или другой информации, которую необходимо сохранить в выходных данных) — это комментарии, прикрепленные к узлам верхнего уровня.

Опция unsafe compress_

Он позволяет выполнять некоторые преобразования, которые могут нарушить логику кода в некоторых надуманных случаях, но этого вполне достаточно для большинства кодов. Возможно, вы захотите попробовать это на своем собственном коде, это должно уменьшить минимизированный размер. Вот что происходит, когда этот флаг включен:

  • new Array(1, 2, 3)или Array(1, 2, 3)[ 1, 2, 3 ]
  • new Object(){}
  • String(exp)или exp.toString()"" + exp
  • new Object/RegExp/Function/Error/Array (...)→ мы отбрасываемnew

Conditional compilation

Вы можете использовать переключатель --define( -d), чтобы объявить глобальные переменные, которые UglifyJS будет считать константами (если они не определены в области видимости). Например, если вы его передадите --define DEBUG=false, в сочетании с удалением мертвого кода UglifyJS отбросит из вывода следующее:

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

Вы можете указать вложенные константы в форме --define env.DEBUG=false.

UglifyJS будет предупреждать о том, что условие всегда ложно и об удалении недостижимого кода; на данный момент нет возможности отключить только это конкретное предупреждение, вы можете отключить warnings=falseвсе предупреждения .

Другой способ сделать это — объявить глобальные переменные как константы в отдельном файле и включить их в сборку. Например, у вас может быть файл build/defines.jsсо следующим:

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

и создайте свой код следующим образом:

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

UglifyJS заметит константы и, поскольку их нельзя изменить, он оценит ссылки на них как само значение и отбросит недоступный код, как обычно. Сборка будет содержать объявления, constесли вы их используете. Если вы ориентируетесь на среду < ES6, которая делает не поддерживается const, использования varwith reduce_vars(включено по умолчанию) должно быть достаточно.

Conditional compilation API

Вы также можете использовать условную компиляцию через программный API, с той разницей, что имя свойства global_defsявляется свойством компрессора:

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

Чтобы заменить идентификатор произвольным непостоянным выражением, необходимо добавить global_defsк ключу префикс, "@"чтобы указать UglifyJS проанализировать значение как выражение:

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

В противном случае он будет заменен строковым литералом:

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

Использование собственного Uglify AST с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

Трансверсализацию и трансформацию нативного АСТ можно осуществлять посредством TreeWalkerи TreeTransformer соответственно.

ESTree / SpiderMonkey AST

UglifyJS имеет свой собственный формат абстрактного синтаксического дерева; по практическим соображениям мы не можем легко перейти на внутреннее использование AST SpiderMonkey. Однако в UglifyJS теперь есть конвертер, который может импортировать AST SpiderMonkey.

Например, Acorn — это сверхбыстрый парсер, который создает AST SpiderMonkey. У него есть небольшая утилита CLI, которая анализирует один файл и выводит AST в формате JSON на стандартный вывод. Чтобы использовать UglifyJS для искажения и сжатия этого:

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

Опция -p spidermonkeyсообщает UglifyJS, что все входные файлы — это не JavaScript, а код JS, описанный в SpiderMonkey AST в JSON. Поэтому в этом случае мы не используем собственный парсер, а просто преобразуем этот AST во внутренний AST.

Use Acorn for parsing

Для развлечения я добавил -p acornопцию, которая будет использовать Acorn для выполнения всего синтаксического анализа. Если вы укажете эту опцию, UglifyJS будет использовать require("acorn").

Acorn действительно быстр (например, 250 мс вместо 380 мс для кода размером 650 КБ), но преобразование дерева SpiderMonkey, которое создает Acorn, занимает еще 150 мс, так что в целом это немного больше, чем просто использование собственного синтаксического анализатора UglifyJS.

Uglify Fast Minify Mode

Это малоизвестно, но удаление пробелов и искажение символов обеспечивают 95% уменьшения размера минимизированного кода для большинства JavaScript, а не сложные преобразования кода.Можно просто отключить, compressчтобы ускорить сборку Uglify в 3-4 раза.В этом быстром mangle- Единственный режим Uglify имеет сравнимую скорость минимизации и размеры gzip с butternut:

d3.js уменьшить размер размер gzip минимизировать время (секунды)
оригинальный 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
орех @ 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

Чтобы включить режим быстрого минимизации из CLI, используйте:

1
uglifyjs file.js -m

Чтобы включить режим быстрого минимизации с помощью API, используйте:

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

Исходные карты и отладка

Известно, что различные compressпреобразования, которые упрощают, реорганизуют, встраивают и удаляют код, отрицательно влияют на отладку с использованием карт исходного кода. Это ожидаемо, поскольку код оптимизирован, а сопоставления часто просто невозможны, поскольку некоторый код больше не существует. Для максимальной точности исходного кода отладка карты отключите опцию Uglify compressи просто используйте mangle.

Compiler assumptions

Чтобы обеспечить лучшую оптимизацию, компилятор делает различные предположения:

  • .toString()и .valueOf()не имеют побочных эффектов, а для встроенных объектов они не переопределяются.
  • undefinedи NaNне Infinityбыли переопределены извне.
  • arguments.callee, arguments.callerи Function.prototype.callerне используются.
  • Код не ожидает, что содержимое Function.prototype.toString()будет Error.prototype.stackчем-то конкретным.
  • Получение и установка свойств простого объекта не вызывает других побочных эффектов (использование .watch()или Proxy).
  • Свойства объекта можно добавлять, удалять и изменять (это не запрещено с помощью , Object.defineProperty(), Object.defineProperties()или ) .Object.freeze()Object.preventExtensions()Object.seal()