跳至主要内容

CLI 使用

terser [input files] [options]

Terser 可以接受多个输入文件。建议您先传递输入文件,然后再传递选项。Terser 将按顺序解析输入文件并应用任何压缩选项。这些文件在同一个全局作用域中解析,也就是说,从一个文件到另一个文件中声明的某个变量/函数的引用将被正确匹配。

采用选项的命令行参数(如 --parse、--compress、--mangle 和 --format)可以采用以逗号分隔的默认选项覆盖列表。例如

terser input.js --compress ecma=2015,computed_props=false

如果没有指定输入文件,Terser 将从 STDIN 读取。

如果您希望在输入文件之前传递选项,请使用双破折号分隔两者,以防止输入文件被用作选项参数

terser --compress --mangle -- input.js

命令行选项

    -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。

CLI 源码地图选项

Terser 可以生成源码地图文件,这对于调试压缩后的 JavaScript 非常有用。要获取源码地图,请传递 --source-map --output output.js(源码地图将被写入 output.js.map)。

其他选项

  • --source-map "filename='<NAME>'" 指定源码地图的名称。

  • --source-map "root='<URL>'" 传递可以找到原始文件的 URL。

  • --source-map "url='<URL>'" 指定可以找到源码地图的 URL。否则,Terser 假设正在使用 HTTP X-SourceMap,并将省略 //# sourceMappingURL= 指令。

例如

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.jsfile2.js,将输出结果放到 foo.min.js 中,将源码地图放到 foo.min.js.map 中。源码映射将引用 http://foo.com/src/js/file1.jshttp://foo.com/src/js/file2.js(实际上,它将列出 http://foo.com/src 作为源码地图根目录,并将原始文件列为 js/file1.jsjs/file2.js)。

组合源码地图

当您压缩由 CoffeeScript 等编译器输出的 JS 代码时,映射到 JS 代码并不是很有帮助。相反,您希望映射回原始代码(即 CoffeeScript)。Terser 有一个选项可以接受输入源码地图。假设您有一个从 CoffeeScript → 编译后的 JS 的映射,Terser 可以通过将编译后的 JS 中的每个标记映射到其原始位置来生成从 CoffeeScript → 压缩后的 JS 的映射。

要使用此功能,请传递 --source-map "content='/path/to/input/source.map'",如果源码地图包含在源代码中,则传递 --source-map "content=inline"

CLI 压缩选项

您需要传递 --compress (-c) 来启用压缩器。您可以选择传递以逗号分隔的 压缩选项 列表。

选项的格式为 foo=bar,或者只是 foo(后者表示您要设置为 true 的布尔选项;它实际上是 foo=true 的快捷方式)。

例如

terser file.js -c toplevel,sequences=false

CLI 混淆选项

要启用混淆器,您需要传递 --mangle (-m)。支持以下(以逗号分隔的)选项

  • toplevel(默认值 false)-- 混淆在顶级作用域中声明的名称。

  • eval(默认值 false)-- 混淆在使用 evalwith 的作用域中可见的名称。

当启用混淆但您想阻止某些名称被混淆时,可以使用 --mangle reserved 声明这些名称,并传递以逗号分隔的名称列表。例如

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

以防止 requireexports$ 名称被更改。

CLI 混淆属性名称 (--mangle-props)

注意:破坏您的代码。一个好的经验法则是,除非您确切地知道自己在做什么以及这是如何工作的,并且阅读了本节直到最后,否则不要使用此选项。

混淆属性名称是一个单独的步骤,与变量名称混淆不同。传递 --mangle-props 来启用它。使用此选项最不危险的方法是像这样使用 regex 选项

terser example.js -c -m --mangle-props regex=/_$/

这将混淆所有以下划线结尾的属性。因此,您可以使用它来混淆内部方法。

默认情况下,它将混淆输入代码中的所有属性,但内置 DOM 属性和核心 JavaScript 类中的属性除外,如果您不这样做,这将破坏您的代码

  1. 控制您要混淆的所有代码
  2. 避免使用模块打包器,因为它们通常会分别调用每个文件上的 Terser,从而无法在模块之间传递混淆的对象。
  3. 避免调用 definePropertyhasOwnProperty 等函数,因为它们使用字符串引用对象属性,如果您不知道自己在做什么,这将破坏您的代码。

例如

// 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 除外)(非常不安全)

$ 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 属性之外的所有属性(仍然非常不安全)

$ 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 匹配的所有属性(不那么不安全,但仍然不安全)

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

组合混淆属性选项

$ 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 覆盖)。

可以使用正则表达式来定义应该混淆哪些属性名称。例如,--mangle-props regex=/^_/ 将只混淆以下划线开头的属性名称。

当您使用此选项压缩多个文件时,为了使它们最终能够协同工作,我们需要以某种方式确保一个属性在所有文件中都被混淆为相同的名称。为此,请传递 --name-cache filename.json,Terser 会将这些映射保存在一个文件中,然后可以重复使用该文件。它最初应该是空的。例如

$ 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.jspart2.js 在混淆的属性名称方面将彼此一致。

如果您在对 Terser 的单个调用中压缩所有文件,则不需要使用名称缓存。

混淆未加引号的名称 (--mangle-props keep_quoted)

使用加引号的属性名称 (o["foo"]) 会保留属性名称 (foo),以便即使在未加引号的样式 (o.foo) 中使用时,它也不会在整个脚本中被混淆。例如

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

调试属性名称混淆

您还可以传递 --mangle-props debug 来混淆属性名称,而不会完全隐藏它们。例如,使用此选项,属性 o.foo 将被混淆为 o._$foo$_。这允许对大型代码库进行属性混淆,同时仍然能够调试代码并识别混淆在哪里破坏了代码。

$ 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_。您可以在每次编译脚本时更改此设置,以识别属性是如何被混淆的。一种技术是在每次编译时传递一个随机数,以模拟混淆随不同输入(例如,当您使用新属性更新输入脚本时)而发生的变化,并帮助识别将混淆的键写入存储等错误。