天天看點

JavaScript解析器,壓縮器和美化工具包API參考雜

适用于ES6 +的JavaScript解析器,壓縮器和美化工具包.

寫在前面

适用于ES6 +的JavaScript解析器,壓縮器和美化工具包.

uglify-es與API / CLI相容[email protected].

uglify-es不向後相容[email protected].

下載下傳安裝

首先確定已安裝最新版本的node.js (您可能需要在此步驟後重新啟動計算機)

從NPM用作指令行應用程式:

npm install uglify-es -g

指令行用法

uglifyjs [input files] [options]

UglifyJS可以擷取多個輸入檔案。建議您先傳遞輸入檔案,然後傳遞選項。UglifyJS将按順序解析輸入檔案并應用任何壓縮選項。這些檔案在同一個全局範圍内進行解析,即從檔案到另一個檔案中聲明的某個變量/函數的引用将被正确比對。

如果未指定輸入檔案,則UglifyJS将從STDIN讀取。

如果您希望在輸入檔案之前傳遞選項,請使用雙短劃線将兩者分開以防止輸入檔案用作選項參數:

uglifyjs --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.

                                `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.

    --ecma <version>            Specify ECMAScript release: 5, 6, 7 or 8.

    --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-classnames           Do not mangle/drop class names.

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

    --safari10                  Support non-standard Safari 10/11.

                                Equivalent to setting `safari10: true` in `minify()`

                                for `mangle` and `output` options.

                                By default `uglify-es` will not work around

                                Safari 10/11 bugs.

    --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非常有用。要擷取源地圖,請傳遞 --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=指令。

例如:

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

組合源圖

當您壓縮由編譯器(如CoffeeScript)輸出的JS代碼時,映射到JS代碼将不會太有用。相反,您想要映射回原始代碼(即CoffeeScript)。UglifyJS可以選擇輸入源地圖。假設您有來自CoffeeScript→已編譯JS的映射,UglifyJS可以通過将已編譯JS中的每個标記映射到其原始位置,從CoffeeScript→壓縮JS生成映射。

要使用此功能傳遞,--source-map "content='/path/to/input/source.map'" 或者--source-map "content=inline"源源地圖是否與源内聯。

CLI壓縮選項

您需要傳遞--compress(-c)以啟用壓縮器。您可以選擇傳遞逗号分隔的壓縮選項清單。

選項在表單中foo=bar,或者隻是foo(後者意味着您要設定的布爾選項true;它實際上是一個快捷方式foo=true)。

例:

uglifyjs file.js -c toplevel,sequences=false

CLI mangle選項

要啟用mangler,您需要傳遞--mangle(-m)。支援以下(逗号分隔)選項:

toplevel(預設false) - 在頂級範圍内聲明的mangle名稱。

eval(預設false) - 在使用eval或with使用的範圍内可見的mangle名稱。

啟用修改但是您希望阻止某些名稱被修改時,您可以使用--mangle reserved- 通過逗号分隔的名稱清單來聲明這些名稱。例如:

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

阻止require,exports并$從名字是改了。

CLI修改屬性名稱(--mangle-props)

注意:這可能會破壞您的代碼。Mangling屬性名稱是一個單獨的步驟,與變量名稱修改不同。通過 --mangle-props啟用它。它将破壞輸入代碼中的所有屬性,但核心JavaScript類中的内置DOM屬性和屬性除外。例如:

// example.jsvar x = {

    baz_: 0,

    foo_: 1,

    calc: function() {

        return this.foo_ + this.baz_;

    }

};x.bar_ = 2;

x["baz_"] = 3;console.log(x.calc());

對所有屬性進行管理(JavaScript除外builtins):

$ uglifyjs example.js -c -m --mangle-props

var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());

對屬性以外的所有屬性進行管理reserved:

$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]

var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());

切換所有比對的屬性regex:

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

var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());

結合mangle屬性選項:

$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]

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=/^_/隻會破壞以下劃線開頭的屬性名稱。

當您使用此選項壓縮多個檔案時,為了使它們最終一起工作,我們需要確定某個屬性在所有屬性中被破壞為相同的名稱。為此,pass --name-cache filename.json 和UglifyJS将這些映射儲存在一個檔案中,然後可以重複使用。它應該是最初為空的。例:

$ RM -f /tmp/cache.json   #重新開始 

$ uglifyjs file1.js file2.js --mangle道具--name緩存/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中壓縮所有檔案,則無需使用名稱緩存。

Mancling unquoted names(--mangle-props keep_quoted)

使用帶引号的屬性name(o["foo"])保留屬性name(foo),這樣即使在非引用樣式(o.foo)中使用它也不會在整個腳本中被破壞。例:

// stuff.jsvar o = {

    "foo": 1,

    bar: 3

};o.foo += o.bar;console.log(o.foo);

$ uglifyjs stuff.js --mangle-props keep_quoted -c -m

var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);

調試屬性名稱mangling

您也可以傳遞--mangle-props debug以破壞屬性名稱而不會完全遮蓋它們。例如,該屬性o.foo 将o._$foo$_使用此選項進行修改。這允許對大型代碼庫進行屬性修改,同時仍然能夠調試代碼并識别破壞事件的位置。

$ uglifyjs 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_。每次編譯腳本時都可以更改此項,以确定屬性是如何被破壞的。一種技術是在每次編譯時傳遞一個随機數,以模拟使用不同輸入更改的修改(例如,當您使用新屬性更新輸入腳本時),并幫助識别錯誤,例如将損壞的密鑰寫入存儲。

API參考

假設通過NPM安裝,您可以在您的應用程式中加載UglifyJS,如下所示:

var UglifyJS =  require(“ uglify-es ”);

有一個進階功能,minify(code, options)它将以可配置的方式執行所有縮小階段。預設情況下minify()将啟用選項compress和mangle。例:

var code = "function add(first, second) { return first + second; }";var result = UglifyJS.minify(code);console.log(result.error); // runtime error, or `undefined` if no errorconsole.log(result.code);  // minified output: function add(n,d){return n+d}

minify通過使用第一個參數的對象,一次可以有多個JavaScript檔案,其中鍵是檔案名,值是源代碼:

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選項:

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選項:

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

您可以通過以下方式将名稱緩存持久儲存到檔案系統:

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()選項組合的示例:

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: ""

    }

};var result = UglifyJS.minify(code, options);console.log(result.code);// // alert(10);"

發出警告:

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 caseconsole.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ]console.log(result.code);     // function f(){return 5}

一個錯誤示例:

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}

注意:與API 不同[email protected],3.xAPI不會抛出錯誤。為了達到類似的效果,可以執行以下操作:

var result = UglifyJS.minify(code, options);if (result.error) throw result.error;

縮小選項

ecma(預設undefined) -通過5,6,7或8重寫parse, compress和output選項。

warnings(預設false) - 傳遞true以傳回壓縮機警告result.warnings。使用該值"verbose"可獲得更詳細的警告。

parse(預設{}) - 如果要指定一些其他解析選項,則傳遞對象。

compress(預設{}) - 傳遞false以完全跳過壓縮。傳遞對象以指定自定義壓縮選項。

mangle(預設true) - 傳遞false以跳過重整名稱,或傳遞一個對象來指定mangle選項(見下文)。

    • mangle.properties(預設false) - mangle選項的子類别。傳遞對象以指定自定義mangle屬性選項。

output(預設null) - 如果要指定其他輸出選項,則傳遞對象。預設值針對最佳壓縮進行了優化。

sourceMap(預設false) - 如果要指定源映射選項,則傳遞對象 。

toplevel(預設false) - true如果要啟用頂級變量和函數名稱修改并删除未使用的變量和函數,則設定為。

nameCache(預設null) - 如果您希望跨多個調用緩存損壞的變量和屬性名稱,則傳遞一個空對象{}或以前使用過的nameCache對象minify()。注意:這是一個讀/寫屬性。minify()将讀取此對象的名稱緩存狀态,并在縮小期間更新它,以便使用者可以重複使用或外部持久化。

ie8(預設false) - 設定true為支援IE8。

keep_classnames(預設值:) undefined- 傳遞true以防止丢棄或破壞類名。

keep_fnames(預設值:) false- 傳遞true以防止丢棄或損壞函數名稱。對于依賴的代碼很有用Function.prototype.name。如果頂級minify選項keep_classnames是undefined,它将覆寫頂級minify選項的值keep_fnames。

safari10(預設:) - 在循環範圍界定和false傳遞true解決Safari 10/11錯誤await。見safari10在選擇mangle 和output了解詳細資訊。

縮小選項結構

{

    parse : {

         // parse options 

    },

    compress : {

         // compress options 

    },

    mangle : {

         // mangle options 

        properties : {

             // mangle property options 

        }

    },

    output : {

         // output options 

    },

    sourceMap : {

         / / source map options 

    },

    ecma : 5,//指定以下之一:5,6,7或8 

    keep_classnames : false,

    keep_fnames : false,

    ie8 : false,

    nameCache : null,//或指定名稱緩存對象 

    safari10 : false,

    toplevel : false,

    warnings : false,

}

源地圖選項

要生成源映射:

var result = UglifyJS.minify({"file1.js": "var a = function() {};"}, {

    sourceMap: {

        filename: "out.js",

        url: "out.js.map"

    }

});console.log(result.code); // minified outputconsole.log(result.map);  // source map

請注意,源映射不會儲存在檔案中,而是剛剛傳回 result.map。通過了該值sourceMap.url僅用于設定 //# sourceMappingURL=out.js.map在result.code。值 filename僅用于設定源映射檔案中的file屬性(請參閱規範)。

您可以将選項設定sourceMap.url為be "inline",源地圖将附加到代碼中。

您還可以指定要包含在源映射中的sourceRoot屬性:

var result =  UglifyJS。minify({ “ file1.js ”: “ var a = function(){}; ” },{

    sourceMap : {

        root : “ http://example.com/src ”,

        url : “ out.js.map ” 

    }

});

如果您正在壓縮已編譯的JavaScript并為其建立源映射,則可以使用sourceMap.content:

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`

解析選項

bare_returns(預設false) - 支援頂級return語句

ecma(預設8) -指定的一個5,6,7或8。注意:此設定目前不會強制執行,除了函數參數清單中的ES8可選尾随逗号和調用ecma 8。

html5_comments(預設true)

shebang(預設true) - 支援#!command作為第一行

壓縮選項

arrows(預設值true:) - 轉換()=>{return x}為()=>x。如果結果代碼更短,則類和對象文字方法也将轉換為箭頭表達式:m(){return x}變為m:()=>x。此轉換要求将ecmacompress選項設定為6或更大。

booleans(預設true值:) - 例如,對布爾上下文的各種優化!!a ? b : c → a ? b : c

collapse_vars(預設值true:) - 折疊單次使用的非常數變量,允許副作用。

comparisons(預設true值:) - 對二進制節點應用某些優化,例如!(a <= b) → a > b(僅當unsafe_comps),嘗試否定二進制節點,例如a = !b && !c && !d && !e → a=!(b||c||d||e)等。

computed_props(預設true值:) - 将常量計算屬性轉換為正常屬性:{["computed"]: 1}轉換為{computed: 1}。

conditionals(預設值:) true- 對if-s和條件表達式應用優化

dead_code(預設true:) - 删除無法通路的代碼

drop_console(預設值:) false- 傳遞true放棄對console.*函數的調用 。如果您希望在删除函數調用後删除特定的函數調用,例如console.info和/或保留函數參數的副作用,請pure_funcs改用。

drop_debugger(預設:) true- 删除debugger;語句

ecma(預設值:) 5- 傳遞6或更高以啟用compress将ES5代碼轉換為較小的ES6 +等效形式的選項。

evaluate(預設值:) true- 嘗試計算常量表達式

expression(預設值false:) - 傳遞true以保留終端語句中的完成值,而不用return例如在bookmarklet中。

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:) - 使用simple / returnstatement進行内聯調用:

    • false - 與...一樣 0
    • 0 - 禁用内聯
    • 1 - 内聯簡單功能
    • 2 - 帶參數的内聯函數
    • 3 - 帶參數和變量的内聯函數
    • true - 與...一樣 3

join_vars(預設true:) - 加入連續的var語句

keep_classnames(預設值false:) - 傳遞true以防止壓縮器丢棄類名。另請參見:keep_classnames mangle選項。

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:) - 否定傳回值被丢棄的“立即調用的函數表達式”,以避免代碼生成器插入的parens。

passes(預設值:) 1- 運作compress的最大次數。在某些情況下,多次傳遞會導緻進一步壓縮的代碼。請記住,更多通行證需要更多時間。

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_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以禁用标記為“純”的可能丢棄的功能。如果注釋注釋或緊接在調用之前,函數調用将标記為“純” 。例如: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_arrows(預設值false:) - 如果函數體未引用,則将ES5樣式的匿名函數表達式轉換為箭頭函數this。注意:如果代碼依賴于prototype箭頭函數缺少的函數,則執行此轉換并不總是安全的。此轉換要求将ecmacompress選項設定為6或更大。

unsafe_comps(預設值:false) -反向<并<=以>和>=以允許改善的壓縮。當兩個操作數中的至少一個是具有計算值的對象時,這可能是不安全的,因為使用了像get或等方法valueOf。在比較中的操作數切換之後,這可能導緻執行順序的改變。如果兩個壓縮隻能comparisons和 unsafe_comps都設定為true。

unsafe_Function(預設false) -壓縮和裂傷Function(args, code) 當兩個args和code是字元串文字。

unsafe_math(預設值false:) - 優化像2 * x * 3into 6 * x這樣的數值表達式 ,這可能會給出不精确的浮點結果。

unsafe_methods(預設值:false) - 轉換{ m: function(){} }為 { m(){} }。ecma必須設定為6或更大才能啟用此轉換。如果unsafe_methods是RegExp,則具有與RegExp比對的鍵的鍵/值對将轉換為簡明方法。注意:如果啟用,則存在擷取“ <method name>不是構造函數” 的風險。如果任何代碼嘗試new使用前一個函數,則會出現TypeError 。

unsafe_proto(預設:) false- 優化表達式,如 Array.prototype.slice.call(a)into[].slice.call(a)

unsafe_regexp(預設值:) - 使用與它們是常量相同的方式false啟用變量替換 RegExp。

unsafe_undefined(預設值:) false- 替換void 0是否有一個undefined在作用域中命名的變量(變量名稱将被修改,通常縮減為單個字元)

unused(預設值true:) - 删除未引用的函數和變量(除非設定為,否則簡單的直接變量指派不計為引用"keep_assign")

warnings(預設值false:) - 删除無法通路的代碼或未使用的聲明等時顯示警告

裂縫選項

eval(預設false) - 傳遞true到在使用eval或with使用的範圍中可見的mangle名稱。

keep_classnames(預設false) - 傳遞true給不是mangle類名。另請參見:keep_classnames compress選項。

keep_fnames(預設false) - 傳遞true給非變形函數名稱。對于依賴的代碼很有用Function.prototype.name。另請參見:keep_fnames compress選項。

reserved(預設[]) - 傳遞應該從修改中排除的辨別符數組。示例:["foo", "bar"]。

toplevel(預設false) - 傳遞true到頂級作用域中聲明的mangle名稱。

safari10(預設false) - 傳遞true解決Safari 10循環疊代器錯誤 “無法聲明兩次let變量”。另請參見:safari10 輸出選項。

例子:

// test.js var globalVar;function  funcName( firstLongName, anotherLongName){

     var myVariable = firstLongName +   anotherLongName;

}

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屬性選項

builtins(預設值:) false- true用于允許修改内置DOM屬性。不建議覆寫此設定。

debug(預設值false:) - 原始名稱的Mangle名稱仍然存在。傳遞空字元串""以啟用,或者使用非空字元串來設定調試字尾。

keep_quoted(預設值false:) - 僅修改未引用的屬性名稱。

regex(預設值null:) - 将RegExp文字傳遞給僅與正規表達式比對的屬性名稱。

reserved(預設值[]:) - 不要破壞reserved數組中列出的屬性名稱 。

輸出選項

代碼生成器預設嘗試輸出最短代碼。如果你想要美化輸出,傳遞--beautify(-b)。您可以選擇傳遞控制代碼輸出的其他參數:

ascii_only(預設false) - 轉義字元串和regexps中的Unicode字元(影響非ascii字元變為無效的指令)

beautify(預設true) - 是否真正美化輸出。傳遞-b将此設定為true,但-b即使您想生成縮小的代碼,也可能需要傳遞,以便指定其他參數,以便您可以使用-b beautify=false它來覆寫它。

bracketize(預設false) -總是插在括号中if,for, do,while或with語句,即使他們的身體是一個單獨的語句。

comments(預設false) - 傳遞true或"all"保留所有注釋,"some"保留一些注釋,正規表達式字元串(例如/^!/)或函數。

ecma(預設5) - 設定輸出列印模式。設定ecma為6或更大以發出速記對象屬性 - 即:{a}而不是{a: a}。該ecma選項僅改變直接控制美化器的輸出。抽象文法樹中的不相容功能仍将按原樣輸出。例如:一個ecma的設定5将不會轉換器ES6 +代碼ES5。

indent_level(預設4)

indent_start(預設0) - 用許多空格為所有行添加字首

inline_script(預設值false) - </script在字元串出現時轉義斜杠

keep_quoted_props(預設false) - 啟用時,防止從對象文字中的屬性名稱中删除引号。

max_line_len(預設false) - 最大行長度(對于uglified代碼)

preamble(預設null) - 傳遞時它必須是一個字元串,它将按字面意思添加到輸出中。源地圖将根據此文本進行調整。例如,可用于插入包含許可資訊的注釋。

preserve_line(預設false) - 傳遞true以保留行,但隻有在beautify設定為時才有效false。

quote_keys(預設false) - 傳遞true引用文字對象中的所有鍵

quote_style(預設0) - 字元串的首選引用樣式(也影響引用的屬性名稱和指令):

    • 0 - 更喜歡雙引号,當字元串本身有更多雙引号時,切換到單引号。0最适合gzip大小。
    • 1 - 始終使用單引号
    • 2 - 始終使用雙引号
    • 3 - 始終使用原始報價

safari10(預設false) - 設定此選項以true解決Safari 10/11 await錯誤。另請參見:safari10 mangle選項。

semicolons(預設true) - 用分号分隔語句。如果你通過,false那麼我們将盡可能使用換行符而不是分号,進而導緻更加可讀的uglified代碼輸出(gzip之前的大小可能更小; gzip之後的大小不大)。

shebang(預設true) - #!在序言中保留shebang (bash腳本)

webkit(預設false) - 為WebKit錯誤啟用變通辦法。PhantomJS使用者應該将此選項設定為true。

width(預設80) - 僅在啟用美化時生效,這指定美化者将嘗試遵循的(定向)線寬。它指的是行文本的寬度(不包括縮進)。它目前效果不佳,但它确實使UglifyJS生成的代碼更具可讀性。

wrap_iife(預設false) - 傳遞true以立即包裝調用的函數表達式。有關詳細資訊,請參閱 #640。

保留版權聲明或其他評論

您可以傳遞--comments以保留輸出中的某些注釋。預設情況下,它将保留包含“@preserve”,“@ license”或“@cc_on”的JSDoc樣式注釋(IE的條件編譯)。您可以傳遞 --comments all以保留所有注釋或有效的JavaScript正規表達式,以僅保留與此正規表達式比對的注釋。例如,--comments /^!/ 将保持評論。

但請注意,可能存在注釋丢失的情況。例如:

function  f(){

     / **  @preserve Foo Bar * /

     function  g(){

         //從不調用此函數 

    } 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

條件編譯

您可以使用--define(-d)開關來聲明UglifyJS将假定為常量的全局變量(除非在範圍中定義)。例如,如果你通過,--define DEBUG=false那麼加上死代碼删除,UglifyJS将從輸出中丢棄以下内容:

if (DEBUG) {

    console.log("debug stuff");

}

您可以以--define env.DEBUG=false。的形式指定嵌套常量。

UglifyJS将警告條件總是錯誤并且關于丢棄無法通路的代碼; 目前沒有選項隻關閉此特定警告,您可以通過warnings=false關閉所有警告。

另一種方法是将全局變量聲明為單獨檔案中的常量,并将其包含在建構中。例如,您可以擁有build/defines.js包含以下内容的 檔案:

var  DEBUG  =  false ;var  PRODUCTION  =  true ;//等

并像這樣建構你的代碼:

uglifyjs build/defines.js js/foo.js js/bar.js... -c

UglifyJS将注意到常量,并且由于它們不能被更改,它将評估它們對值本身的引用并像往常一樣丢棄無法通路的代碼。const如果您使用它們,建構将包含聲明。如果您的目标是<ES6不支援的環境,則const使用varwith reduce_vars(預設情況下啟用)應該足夠了。

條件編譯API

您還可以通過程式設計API使用條件編譯。差別在于屬性名稱是global_defs和壓縮器屬性:

var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {

    compress: {

        dead_code: true,

        global_defs: {

            DEBUG: false

        }

    }

});

要使用任意非常量表達式替換辨別符,必須在global_defs鍵前加上,"@"以訓示UglifyJS将值解析為表達式:

UglifyJS.minify("alert('hello');", {

    compress: {

        global_defs: {

            "@alert": "console.log"

        }

    }

}).code;// returns: 'console.log("hello");'

否則它将被替換為字元串文字:

UglifyJS.minify("alert('hello');", {

    compress: {

        global_defs: {

            "alert": "console.log"

        }

    }

}).code;// returns: '"console.log"("hello");'

使用原生的Uglify AST minify()

//示例:僅解析,生成本機Uglify AST

var result =  UglifyJS。minify(code,{

    parse: {},

    compress: false,

    mangle: false,

    output: {

        ast: true,

        code: false   // optional  -  fast if if false 

    }

}); // result.ast包含原生Uglify AST

//示例:接受本機Uglify AST輸入,然後壓縮和修改//           以生成代碼和本機AST。

var result =  UglifyJS。minify(ast,{

    compress: {},

    mangle: {},

    output: {

        ast: true,

        code: true   // optional  -  fast if if false 

    }

}); // result.ast包含原生的Uglify AST // result.code包含字元串形式的縮小代碼。

使用Uglify AST

天然AST的橫向和轉化可分别通過TreeWalker和 進行 TreeTransformer。

ESTree / SpiderMonkey AST

UglifyJS有自己的抽象文法樹格式; 出于 實際原因, 我們無法輕易改變内部使用SpiderMonkey AST。但是,UglifyJS現在有一個可以導入SpiderMonkey AST的轉換器。

例如,Acorn是一個産生SpiderMonkey AST的超快速解析器。它有一個小的CLI實用程式,它解析一個檔案并在标準輸出上以JSON轉儲AST。使用UglifyJS來修改和壓縮:

acorn file.js | uglifyjs -p spidermonkey -m -c

該-p spidermonkey選項告訴UglifyJS所有輸入檔案都不是JavaScript,而是JSON中的SpiderMonkey AST中描述的JS代碼。是以,在這種情況下我們不使用自己的解析器,而隻是将AST轉換為内部AST。

使用Acorn進行解析

更有趣的是,我添加了-p acorn使用Acorn進行所有解析的選項。如果你通過這個選項,UglifyJS會require("acorn")。

Acorn真的很快(例如在650K代碼上250ms而不是380ms),但轉換Acorn生成的SpiderMonkey樹需要另外150ms,是以它總是比使用UglifyJS自己的解析器多一點。

Uglify快速縮小模式

它并不為人所知,但是對于大多數JavaScript而言,空格删除和符号修改占縮小代碼大小減少的95% - 而不是複雜的代碼轉換。人們可以簡單地禁用compress将Uglify版本加速3到4倍。在這種快速mangle模式下,Uglify具有可比較的縮小速度和gzip大小butternut:

d3.js 縮小尺寸 gzip大小 縮短時間(秒)
原版的 451131 108733 -
[email protected] mangle = false,compress = false 316,600 85 245人 0.70
[email protected] mangle = true,compress = false 220216 72730 1.13
[email protected] 217568 72738 1.41
[email protected] mangle = true,compress = true 212511 71560 3.36
[email protected] 210713 72140 12.64

要從CLI啟用快速縮小模式,請使用:

uglifyjs file.js -m

要使用API​​啟用快速縮小模式:

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

源地圖和調試

compress已知各種簡化,重新排列,内聯和删除代碼的轉換會對使用源映射進行調試産生負面影響。這是預期的,因為代碼已經過優化,并且由于某些代碼不再存在,是以通常根本無法進行映射。為了在源映射調試中獲得最高保真度,請禁用Uglify compress選項并使用mangle。

編譯器假設

為了實作更好的優化,編譯器做出了各種假設:

  • .toString()并且.valueOf()沒有副作用,對于内置對象,它們沒有被覆寫。
  • undefined,NaN并Infinity沒有外部重新定義。
  • arguments.callee,arguments.caller并Function.prototype.caller沒有使用。
  • 代碼不期望特定的内容Function.prototype.toString()或 Error.prototype.stack任何内容。
  • 在普通對象上擷取和設定屬性不會導緻其他副作用(使用.watch()或Proxy)。
  • 對象屬性可以被添加,删除和修改(不阻止與 Object.defineProperty(),Object.defineProperties(),Object.freeze(), Object.preventExtensions()或Object.seal())。

繼續閱讀