Замечательный модуль сообщества

UglifyJS 3

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

Примечание:

  • uglify-js@3имеет упрощенный API и интерфейс командной строки , не имеющий обратной совместимости с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. Чтобы получить исходную карту, выполните pass --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

Параметры изменения интерфейса командной строки

Чтобы включить диспетчер, вам необходимо передать --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._());

Исключить все свойства, соответствующие a 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=/^_/будут искажены только имена свойств, начинающиеся с символа подчеркивания.

Когда вы сжимаете несколько файлов, используя эту опцию, для того, чтобы они работали вместе в конце, нам нужно каким-то образом гарантировать, что одно свойство будет искажено на одно и то же имя во всех из них. Для этого передайте, --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, the 3.x` API не выдает ошибок. Чтобы добиться аналогичного эффекта, можно сделать следующее:

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:) -pass 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.urlчтобы быть "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- передать, 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оператором / :

    • 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, whileи forпетли , когда мы можем статически определить состояние.

  • 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то sequencesограничение по умолчанию равно 200. Установите для параметра значение falseили 0 для отключения. Наименьшая sequencesдлина 2. sequencesЗначение 1 задано как эквивалентное trueи как таковое 200. В редких случаях ограничение последовательностей по умолчанию приводит к очень медленному времени сжатия, и в этом случае рекомендуется значение 20или меньше.

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

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

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

  • top_retain(по умолчанию null:) - запретить unusedудаление определенных функций и переменных верхнего уровня (может быть массивом, разделенными запятыми, RegExp или функцией. Подразумевается 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 * 3в 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(по умолчанию []) - передать AN BE Should Массив идентификаторов, изменение которых исключено из примера : ["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массиве.

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

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

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

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

  • braces( по умолчанию false) - Всегда в INSERT брекеты if, for, do, whileили withзаявления, то даже их тело ЕДИНАЯ Оператор IF.

  • 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) - сохранить shebang #!в преамбуле (скрипты 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

Трансверсия и преобразование нативного AST могут быть выполнены через TreeWalkerи TreeTransformer соответственно.

ESTree / SpiderMonkey AST

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

Например, 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 мс в коде 650K), но преобразование дерева 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 = истина, сжатие = ложь 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

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

1
uglifyjs file.js -m

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

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

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

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

Compiler assumptions

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

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