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 для использования в качестве приложения командной строки:
1npm install uglify-js -g
Из NPM для программного использования:
1npm install uglify-js
Использование командной строки
1uglifyjs [input files] [options]
UglifyJS может принимать несколько входных файлов. Рекомендуется сначала передать входные файлы, а затем параметры. UglifyJS будет последовательно анализировать входные файлы и применять любые параметры сжатия. Файлы анализируются в одной глобальной области, то есть в качестве ссылки из файла в некоторую переменную / функцию, объявленную в другом файле, будут правильно сопоставлены.
Если входной файл не указан, UglifyJS будет читать из STDIN.
Если вы хотите передать свои параметры перед входными файлами, разделите их двойным тире, чтобы предотвратить использование входных файлов в качестве аргументов параметров:
1uglifyjs --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
3uglifyjs 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
).
Пример:
1uglifyjs file.js -c toplevel,sequences=false
Параметры изменения интерфейса командной строки
Чтобы включить диспетчер, вам необходимо передать --mangle
( -m
). Поддерживаются следующие параметры (разделенные запятыми):
toplevel
(по умолчаниюfalse
) - изменить имена, объявленные в области верхнего уровня.eval
(по умолчаниюfalse
) - изменить имена, видимые в областях, где используютсяeval
илиwith
.
Когда искажение включено, но вы хотите предотвратить искажение определенных имен, вы можете объявить эти имена с помощью --mangle reserved
- передать список имен, разделенных запятыми. Например:
1uglifyjs ... -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
1var 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_]
1var 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=/_$/
1var 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_]
1var 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
1var 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
1var 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 в свое приложение следующим образом:
1var UglifyJS = require("uglify-js");
Существует одна функция высокого уровня minify(code, options)
,, которая будет выполнять все фазы минификации настраиваемым образом. По умолчанию minify()
будут включены параметры compress
и mangle
. Пример:
1
2
3
4var 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
7var 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
8var 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
16var 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
16var 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
21var 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
6var 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
3var 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
2var 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
:) -passtrue
для предотвращения отбрасывания или искажения имен функций. Полезно для кода, полагающегося на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
8var 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
6var 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
7var 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 / continueinline
(по умолчанию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
10var 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 .
Разное
Keeping copyright notices or other comments
Вы можете передать, --comments
чтобы сохранить определенные комментарии в выводе. По умолчанию он сохранит комментарии в стиле JSDoc, которые содержат «@preserve», «@license» или «@cc_on» (условная компиляция для IE). Вы можете передать,
--comments all
чтобы сохранить все комментарии или допустимое регулярное выражение JavaScript, чтобы оставлять только комментарии, соответствующие этому регулярному выражению. Например, --comments /^!/
будут сохраняться такие комментарии, как /*! Copyright Notice */
.
Учтите, однако, что возможны ситуации, когда комментарии теряются. Например:
1
2
3
4
5
6
7function 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
3if (DEBUG) {
console.log("debug stuff");
}
Вы можете указать вложенные константы в форме --define env.DEBUG=false
.
UglifyJS предупредит о том, что условие всегда ложно, и об удалении недоступного кода; на данный момент нет возможности отключить только это конкретное предупреждение, вы можете перейти, warnings=false
чтобы отключить все предупреждения.
Другой способ сделать это - объявить глобальные переменные как константы в отдельном файле и включить их в сборку. Например, у вас может быть
build/defines.js
файл со следующим:
1
2
3var DEBUG = false;
var PRODUCTION = true;
// etc.
и создайте свой код следующим образом:
1uglifyjs build/defines.js js/foo.js js/bar.js... -c
UglifyJS заметит константы и, поскольку они не могут быть изменены, он будет оценивать ссылки на них на само значение и отбрасывать недостижимый код, как обычно. const
Сборка будет содержать объявления, если вы их используете. Если вы ориентируетесь на среды <ES6, которые делают не поддерживает const
, использование var
with reduce_vars
(по умолчанию включено) должно быть достаточно.
Conditional compilation API
Вы также можете использовать условную компиляцию через программный API. С той разницей, что имя свойства является global_defs
и является свойством компрессора:
1
2
3
4
5
6
7
8var 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
8UglifyJS.minify("alert('hello');", {
compress: {
global_defs: {
"@alert": "console.log"
}
}
}).code;
// returns: 'console.log("hello");'
В противном случае он был бы заменен строковым литералом:
1
2
3
4
5
6
7
8UglifyJS.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 для искажения и сжатия этого:
1acorn 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 |
Чтобы включить режим быстрого уменьшения из интерфейса командной строки, используйте:
1uglifyjs file.js -m
Чтобы включить быстрый режим минимизации с помощью API, используйте:
1UglifyJS.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()
).