跳至主要內容

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 內建函式) (非常不安全)

$ 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_。你可以在每次編譯腳本時變更此字尾,以找出屬性如何被混淆。一種技巧是在每次編譯時傳遞一個隨機數字,以模擬混淆隨不同輸入而變更(例如,當你使用新屬性更新輸入腳本時),並幫助找出錯誤,例如將混淆的鍵寫入儲存體。