CLI 用法
terser [input files] [options]
Terser 可以接受多个输入文件。建议你先传递输入文件,然后传递选项。Terser 将按顺序解析输入文件并应用任何压缩选项。这些文件在相同的全局范围内进行解析,也就是说,从一个文件到另一个文件中声明的某些变量/函数的引用将被正确匹配。
¥Terser can take multiple input files. It's recommended that you pass the input files first, then pass the options. Terser will parse input files in sequence and apply any compression options. The files are parsed in the same global scope, that is, a reference from a file to some variable/function declared in another file will be matched properly.
采用选项的命令行参数(如 --parse、--compress、--mangle 和 --format)可以采用逗号分隔的默认选项覆盖列表。例如:
¥Command line arguments that take options (like --parse, --compress, --mangle and --format) can take in a comma-separated list of default option overrides. For instance:
terser input.js --compress ecma=2015,computed_props=false
如果未指定输入文件,Terser 将从 STDIN 读取。
¥If no input file is specified, Terser will read from STDIN.
如果你希望在输入文件之前传递选项,请用双破折号分隔两者,以防止输入文件被用作选项参数:
¥If you wish to pass your options before the input files, separate the two with a double dash to prevent input files being used as option arguments:
terser --compress --mangle -- input.js
命令行选项
¥Command line options
-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 and DOM
API props.
`debug` Add debug prefix and suffix.
`keep_quoted` Only mangle unquoted properties, quoted
properties are automatically reserved.
`strict` disables quoted properties
being automatically reserved.
`regex` Only mangle matched property names.
`only_annotated` Only mangle properties defined with /*@__MANGLE_PROP__*/.
`reserved` List of names that should not be mangled.
-f, --format [options] Specify format options.
`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.
`wrap_func_args` Wrap function arguments in parenthesis.
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
`spidermonkey` to write Terser 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 e.g. "@license",
or start with "!". You can optionally pass one of the
following arguments to this flag:
- "all" to keep all comments
- `false` to omit comments in the output
- 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.
--ecma <version> Specify ECMAScript release: 5, 2015, 2016, etc.
-e, --enclose [arg[:value]] Embed output in a big function with configurable
arguments and values.
--ie8 Support non-standard Internet Explorer 8.
Equivalent to setting `ie8: true` in `minify()`
for `compress`, `mangle` and `format` options.
By default Terser will not try to be IE-proof.
--keep-classnames Do not mangle/drop class names.
--keep-fnames Do not mangle/drop function names. Useful for
code relying on Function.prototype.name.
--module Input is an ES6 module. If `compress` or `mangle` is
enabled then the `toplevel` option, as well as strict mode,
will be enabled.
--name-cache <file> File to hold mangled name mappings.
--safari10 Support non-standard Safari 10/11.
Equivalent to setting `safari10: true` in `minify()`
for `mangle` and `format` options.
By default `terser` will not work around
Safari 10/11 bugs.
--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.
--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。
¥Specify --output
(-o
) to declare the output file. Otherwise the output
goes to STDOUT.
CLI 源映射选项
¥CLI source map options
Terser 可以生成源映射文件,这对于调试压缩的 JavaScript 非常有用。要获取源映射,请传递 --source-map --output output.js
(源映射将被写出到 output.js.map
)。
¥Terser can generate a source map file, which is highly useful for
debugging your compressed JavaScript. To get a source map, pass
--source-map --output output.js
(source map will be written out to
output.js.map
).
其他选项:
¥Additional options:
-
--source-map "filename='<NAME>'"
指定源映射的名称。¥
--source-map "filename='<NAME>'"
to specify the name of the source map. -
--source-map "root='<URL>'"
传递可以找到原始文件的 URL。¥
--source-map "root='<URL>'"
to pass the URL where the original files can be found. -
--source-map "url='<URL>'"
指定可以找到源映射的 URL。否则,Terser 假定正在使用 HTTPX-SourceMap
并将省略//# sourceMappingURL=
指令。¥
--source-map "url='<URL>'"
to specify the URL where the source map can be found. Otherwise Terser assumes HTTPX-SourceMap
is being used and will omit the//# sourceMappingURL=
directive.
例如:
¥For example:
terser 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
)。
¥The above will compress and mangle file1.js
and file2.js
, will drop the
output in foo.min.js
and the source map in foo.min.js.map
. The source
mapping will refer to http://foo.com/src/js/file1.js
and
http://foo.com/src/js/file2.js
(in fact it will list http://foo.com/src
as the source map root, and the original files as js/file1.js
and
js/file2.js
).
组合源映射
¥Composed source map
当你压缩由 CoffeeScript 等编译器输出的 JS 代码时,映射到 JS 代码不会有太大帮助。相反,你希望映射回原始代码(即 CoffeeScript)。Terser 可以选择获取输入源映射。假设你有一个来自 CoffeeScript → 已编译 JS 的映射,Terser 可以通过将已编译 JS 中的每个标记映射到其原始位置,从 CoffeeScript → 压缩 JS 生成一个映射。
¥When you're compressing JS code that was output by a compiler such as CoffeeScript, mapping to the JS code won't be too helpful. Instead, you'd like to map back to the original code (i.e. CoffeeScript). Terser has an option to take an input source map. Assuming you have a mapping from CoffeeScript → compiled JS, Terser can generate a map from CoffeeScript → compressed JS by mapping every token in the compiled JS to its original location.
如果源映射包含在源中,则要使用此功能,请传递 --source-map "content='/path/to/input/source.map'"
或 --source-map "content=inline"
。
¥To use this feature pass --source-map "content='/path/to/input/source.map'"
or --source-map "content=inline"
if the source map is included inline with
the sources.
CLI 压缩选项
¥CLI compress options
你需要通过 --compress
(-c
) 来启用压缩器。你可以选择传递以逗号分隔的 压缩选项 列表。
¥You need to pass --compress
(-c
) to enable the compressor. Optionally
you can pass a comma-separated list of compress options.
选项的形式为 foo=bar
,或只是 foo
(后者意味着你要设置 true
的布尔选项;它实际上是 foo=true
的快捷方式)。
¥Options are in the form foo=bar
, or just foo
(the latter implies
a boolean option that you want to set true
; it's effectively a
shortcut for foo=true
).
示例:
¥Example:
terser file.js -c toplevel,sequences=false
CLI 混淆选项
¥CLI mangle options
要启用 mangler,你需要通过 --mangle
(-m
)。支持以下(逗号分隔)选项:
¥To enable the mangler you need to pass --mangle
(-m
). The following
(comma-separated) options are supported:
toplevel
(默认值false
) --
在顶层范围中声明的 mangle 名称。
¥mangle names declared in the top level scope.
eval
(默认值false
) --
mangle 名称在使用 eval
或 with
的范围内可见。
¥mangle names visible in scopes where eval
or with
are used.
当启用重整但你希望防止某些名称被重整时,你可以使用 --mangle reserved
声明这些名称 - 传递以逗号分隔的名称列表。例如:
¥When mangling is enabled but you want to prevent certain names from being
mangled, you can declare those names with --mangle reserved
— pass a
comma-separated list of names. For example:
terser ... -m reserved=['$','require','exports']
以防止 require
、exports
和 $
名称被更改。
¥to prevent the require
, exports
and $
names from being changed.
CLI 修改属性名称 (--mangle-props
)
¥CLI mangling property names (--mangle-props
)
注意:THIS WILL BREAK YOUR CODE.一个好的经验法则是不要使用它,除非你确切地知道自己在做什么以及它是如何工作的,并阅读本节直到最后。
¥Note: THIS WILL BREAK YOUR CODE. A good rule of thumb is not to use this unless you know exactly what you're doing and how this works and read this section until the end.
修改属性名称是一个单独的步骤,与变量名称修改不同。通过 --mangle-props
来启用它。使用此功能最危险的方法是使用 regex
选项,如下所示:
¥Mangling property names is a separate step, different from variable name mangling. Pass
--mangle-props
to enable it. The least dangerous
way to use this is to use the regex
option like so:
terser example.js -c -m --mangle-props regex=/_$/
这将破坏所有以下划线结尾的属性。所以你可以用它来破坏内部方法。
¥This will mangle all properties that end with an underscore. So you can use it to mangle internal methods.
默认情况下,它会破坏输入代码中的所有属性,但内置 DOM 属性和核心 JavaScript 类中的属性除外,如果你不这样做,这将破坏你的代码:
¥By default, it will mangle all properties in the input code with the exception of built in DOM properties and properties in core JavaScript classes, which is what will break your code if you don't:
-
控制你正在修改的所有代码
¥Control all the code you're mangling
-
避免使用模块打包器,因为它们通常会单独对每个文件调用 Terser,从而无法在模块之间传递混淆的对象。
¥Avoid using a module bundler, as they usually will call Terser on each file individually, making it impossible to pass mangled objects between modules.
-
避免调用
defineProperty
或hasOwnProperty
等函数,因为它们使用字符串引用对象属性,如果你不知道自己在做什么,它们会破坏你的代码。¥Avoid calling functions like
defineProperty
orhasOwnProperty
, because they refer to object properties using strings and will break your code if you don't know what you are doing.
一个例子:
¥An example:
// example.js
var x = {
baz_: 0,
foo_: 1,
calc: function() {
return this.foo_ + this.baz_;
}
};
x.bar_ = 2;
x["baz_"] = 3;
console.log(x.calc());
Mangle 所有属性(除了 JavaScript builtins
)(非常不安全):
¥Mangle all properties (except for JavaScript builtins
) (very unsafe):
$ terser example.js -c passes=2 -m --mangle-props
var x={o:3,t:1,i:function(){return this.t+this.o},s:2};console.log(x.i());
破坏除 reserved
属性之外的所有属性(仍然非常不安全):
¥Mangle all properties except for reserved
properties (still very unsafe):
$ terser example.js -c passes=2 -m --mangle-props reserved=[foo_,bar_]
var x={o:3,foo_:1,t:function(){return this.foo_+this.o},bar_:2};console.log(x.t());
破坏与 regex
匹配的所有属性(虽然不是不安全,但仍然不安全):
¥Mangle all properties matching a regex
(not as unsafe but still unsafe):
$ terser example.js -c passes=2 -m --mangle-props regex=/_$/
var x={o:3,t:1,calc:function(){return this.t+this.o},i:2};console.log(x.calc());
组合混淆属性选项:
¥Combining mangle properties options:
$ terser example.js -c passes=2 -m --mangle-props regex=/_$/,reserved=[bar_]
var x={o:3,t:1,calc:function(){return this.t+this.o},bar_:2};console.log(x.calc());
为了让它发挥作用,我们默认避免破坏标准 JS 名称和 DOM API 属性(需要覆盖 --mangle-props builtins
)。
¥In order for this to be of any use, we avoid mangling standard JS names and DOM
API properties by default (--mangle-props builtins
to override).
正则表达式可用于定义应修改哪些属性名称。例如,--mangle-props regex=/^_/
只会修改以下划线开头的属性名称。
¥A regular expression can be used to define which property names should be
mangled. For example, --mangle-props regex=/^_/
will only mangle property
names that start with an underscore.
当你使用此选项压缩多个文件时,为了使它们最终能够一起工作,我们需要以某种方式确保所有文件中的一个属性被破坏为相同的名称。为此,pass --name-cache filename.json
和 Terser 将在一个文件中维护这些映射,然后可以重复使用该文件。它最初应该是空的。示例:
¥When you compress multiple files using this option, in order for them to
work together in the end we need to ensure somehow that one property gets
mangled to the same name in all of them. For this, pass --name-cache filename.json
and Terser will maintain these mappings in a file which can then be reused.
It should be initially empty. Example:
$ rm -f /tmp/cache.json # start fresh
$ terser file1.js file2.js --mangle-props --name-cache /tmp/cache.json -o part1.js
$ terser file3.js file4.js --mangle-props --name-cache /tmp/cache.json -o part2.js
现在,part1.js
和 part2.js
在混淆的属性名称方面将彼此一致。
¥Now, part1.js
and part2.js
will be consistent with each other in terms
of mangled property names.
如果你在一次调用 Terser 中压缩所有文件,则无需使用名称缓存。
¥Using the name cache is not necessary if you compress all your files in a single call to Terser.
修改不带引号的名称 (--mangle-props keep_quoted
)
¥Mangling unquoted names (--mangle-props keep_quoted
)
使用带引号的属性名称 (o["foo"]
) 会保留属性名称 (foo
),这样即使在不带引号的样式 (o.foo
) 中使用,它也不会在整个脚本中被破坏。示例:
¥Using quoted property name (o["foo"]
) reserves the property name (foo
)
so that it is not mangled throughout the entire script even when used in an
unquoted style (o.foo
). Example:
// stuff.js
var o = {
"foo": 1,
bar: 3
};
o.foo += o.bar;
console.log(o.foo);
$ terser stuff.js --mangle-props keep_quoted -c -m
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$_
。这允许对大型代码库进行属性修改,同时仍然能够调试代码并确定修改在哪里破坏了东西。
¥You can also pass --mangle-props debug
in order to mangle property names
without completely obscuring them. For example the property o.foo
would mangle to o._$foo$_
with this option. This allows property mangling
of a large codebase while still being able to debug the code and identify
where mangling is breaking things.
$ terser stuff.js --mangle-props debug -c -m
var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
你还可以使用 --mangle-props debug=XYZ
传递自定义后缀。这会将 o.foo
破坏为 o._$foo$XYZ_
。你可以在每次编译脚本时更改此设置,以识别属性是如何被破坏的。一种技术是在每次编译时传递一个随机数,以模拟不同输入的混淆变化(例如,当你使用新属性更新输入脚本时),并帮助识别错误,例如将混淆的密钥写入存储。
¥You can also pass a custom suffix using --mangle-props debug=XYZ
. This would then
mangle o.foo
to o._$foo$XYZ_
. You can change this each time you compile a
script to identify how a property got mangled. One technique is to pass a
random number on every compile to simulate mangling changing with different
inputs (e.g. as you update the input script with new properties), and to help
identify mistakes like writing mangled keys to storage.