小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

用UglifyJS解析/壓縮/格式化你的Javascript

 aaie_ 2014-08-07

UglifyJS是基于 NodeJS 的Javascript語(yǔ)法解析/壓縮/格式化工具,它支持任何CommonJS模塊系統(tǒng)的Javascript平臺(tái)(實(shí)現(xiàn)自己的CommonJS平臺(tái)也非難事)。 UglifyJS通過(guò)解析重新生成JS代碼的語(yǔ)法樹,你可以通過(guò)AST以了解更多代碼情況,或者自己來(lái)做一個(gè)不同的實(shí)現(xiàn)。UglifyJS解析器是在 parse-js.js 中實(shí)現(xiàn)的,它是非常優(yōu)秀的 parse。

 非安全轉(zhuǎn)換

UglifyJS是基于 NodeJS 的Javascript語(yǔ)法解析/壓縮/格式化工具,它支持任何CommonJS模塊系統(tǒng)的Javascript平臺(tái)(實(shí)現(xiàn)自己的CommonJS平臺(tái)也非難事)。

UglifyJS通過(guò)解析重新生成JS代碼的語(yǔ)法樹,你可以通過(guò)AST以了解更多代碼情況,或者自己來(lái)做一個(gè)不同的實(shí)現(xiàn)。UglifyJS解析器是在 parse-js.js 中實(shí)現(xiàn)的,它是非常優(yōu)秀的 parse-js Common Lisp Library 的一部分。

(如果你正在查找UglifyJS的Common Lisp版本,點(diǎn)擊 這里 )

UglifyJS的另一個(gè)重要部分是在 process.js 實(shí)現(xiàn)的,它用于檢查并實(shí)現(xiàn)解析生成的AST: 

    • 通過(guò)AST進(jìn)行Javascript代碼的重新生成 :如果你想格式化已經(jīng)被壓縮過(guò)的代碼,可以選擇縮進(jìn)參數(shù)。你也可以打印出無(wú)空白(whitespace)的AST,以達(dá)到壓縮的目的。
    • 縮短變量名 :UglifyJS通過(guò)分析代碼并生成新的變量名稱,依賴于作用域,這些名稱通常被簡(jiǎn)化為單一字符,并能足夠智能的處理全局變量,或者eval()調(diào)用及with{}塊。換句話說(shuō),如果在某個(gè)作用域內(nèi)使用了eval()或with{},那么該作用域的所有變量及其父作用域的變量都不會(huì)被重新命名,并且所有指向這類變量的引用也不會(huì)被改變。
    • 以下是一些優(yōu)化規(guī)則會(huì)讓代碼更簡(jiǎn)潔更高效 : 
        • foo["bar"] ==> foo.bar
        • 刪除塊標(biāo)記{}
        • 合并變量聲明: var a = 10; var b = 20; ==> var a=10,b=20;
        • 計(jì)算簡(jiǎn)單的常量表達(dá)式:1 + 2 * 3 ==> 7. UglifyJS只替換計(jì)算結(jié)果比實(shí)際表達(dá)式字節(jié)更少的情況;比如 1/3 結(jié)果為 0.333333333333,因此不會(huì)被替換。
        • 連續(xù)的語(yǔ)句塊會(huì)被合并為一個(gè)序列;大多情況下,這將保留一個(gè)語(yǔ)句,接下來(lái)塊括號(hào)可以被移除。
        • IF語(yǔ)句的優(yōu)化 : 
            • if (foo) bar(); else baz(); ==> foo?bar():baz();
            • if (!foo) bar(); else baz(); ==> foo?baz():bar();
            • if (foo) bar(); ==> foo&&bar();
            • if (!foo) bar(); ==> foo||bar();
            • if (foo) return bar(); else return baz(); ==> return foo?bar():baz();
            • if (foo) return bar(); else something(); ==> {if(foo)return bar();something()} 
        • 移除不會(huì)被用到的代碼并會(huì)給出警告。 

非安全轉(zhuǎn)換

UglifyJS在保留語(yǔ)義的同時(shí)會(huì)盡量提高壓縮比率,如果經(jīng)過(guò)UglifyJS處理后你的代碼邏輯失效了,或?qū)glifyJS的優(yōu)化實(shí)現(xiàn)有更好的想法,都可有直接聯(lián)系作者。 

涉及到全局?jǐn)?shù)組構(gòu)造函數(shù)的調(diào)用 

這時(shí)會(huì)進(jìn)行如下轉(zhuǎn)換:

newArray(1,2,3,4)=>[1,2,3,4]Array(a, b, c)=>[a,b,c]newArray(5)=>Array(5)newArray(a)=>Array(a)

在Array沒有被重新定義之前,這些轉(zhuǎn)換是安全的。UglifyJS也會(huì)對(duì)經(jīng)過(guò)用戶本地或全局重定義的Array進(jìn)行處理,但CSSer建議還是不要這么做:

// case 1.  全局聲明varArray;newArray(1,2, www.csser.com);Array(a, b);// 或者后聲明newArray(1,2,3);varArray;// 或者定義為函數(shù)newArray(1,2,3);functionArray(){...}// case 2. 在函數(shù)內(nèi)部聲明(function(){
    a =newArray(1,2,3);
    b =Array(5,6);varArray;})();// 或者(function(Array){returnArray(5,6,7);})();// 或者(function(){returnnewArray(1,2,3,4);functionArray(){...}})();

// 等等.

安裝 

通過(guò)NPM安裝 

UglifyJS已經(jīng)可以通過(guò)NPM進(jìn)行安裝:

npm install uglify-js 

通過(guò)GitHub安裝最新版本 

## 克隆倉(cāng)庫(kù)
mkdir -p /where/you/wanna/put/it
cd /where/you/wanna/put/it
git clone git://github.com/mishoo/UglifyJS.git## 讓uglify模塊對(duì)NodeJS有效
mkdir -p ~/.node_libraries/
cd ~/.node_libraries/
ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js

## 支持命令行的方式調(diào)用
mkdir -p ~/bin
cd ~/bin
ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
  # (然后將 ~/bin 增加到 $PATH)

如何使用

UglifyJS提供了命令行工具,支持shell腳本的操作需要:

uglifyjs [選項(xiàng)...][文件名]

最后一個(gè)參數(shù)是要處理的JS文件名,如果不指定,則從標(biāo)準(zhǔn)輸入(STDIN)讀取。

支持的選項(xiàng) :

    • -b 或 --beautify - 輸出格式化代碼,當(dāng)傳入該參數(shù),下面的附加選項(xiàng)用于更美觀的控制格式化: 
        • -i N 或 --indent N - 縮進(jìn)級(jí)別(空格數(shù)量)
        • -q 或 --quote-keys - 是否用引號(hào)引起字符串對(duì)象的鍵(默認(rèn)只會(huì)引起不能被正確標(biāo)志的鍵名) 
    • --ascii -默認(rèn) UglifyJS 不處理字符編碼而直接輸出 Unicode 字符,通過(guò)傳入該參數(shù)將非ASCII編碼的字符轉(zhuǎn)化為\cXXXX的序列(輸出總按照UTF8編碼,但傳入該選項(xiàng)能得到ASCII編碼的輸出)。
    • -nm 或 --no-mangle - 不改變變量名稱
    • -ns 或 --no-squeeze - 不調(diào)用 ast_squeeze() 函數(shù)(該函數(shù)會(huì)做多種優(yōu)化使得結(jié)果更小,可讀性略有降低)
    • -mt 或 --mangle-toplevel - 在頂級(jí)作用域打亂變量名稱(默認(rèn)不開啟)
    • --no-seqs - 當(dāng)調(diào)用 ast_squeeze() 將會(huì)合并多個(gè)語(yǔ)句塊為一個(gè)語(yǔ)句塊,如 "a=10; b=20; foo()" 將被轉(zhuǎn)換為 "a=10,b=20,foo()"
    • --no-dead-code - 默認(rèn) UglifyJS 將會(huì)刪除不被用到的代碼,傳入該參數(shù)禁用此功能。
    • -nc 或 --no-copyright - 默認(rèn) uglifyjs 會(huì)在輸出后的代碼中添加版權(quán)信息等注釋代碼,傳入該參數(shù)禁用此功能。
    • -o 文件名 或 --output 文件名 - 指定輸出文件名,如果不指定,則打印到標(biāo)準(zhǔn)輸出(STDOUT)
    • --overwrite - 如果傳入的JS代碼來(lái)自文件而不是標(biāo)準(zhǔn)輸入,傳入該參數(shù),輸出會(huì)覆蓋該文件。
    • --ast - 傳入該參數(shù)會(huì)得到抽象的語(yǔ)法樹而不是Javascript,對(duì)調(diào)試或了解內(nèi)部代碼很有用。
    • -v 或 --verbose - 在標(biāo)準(zhǔn)錯(cuò)誤輸出一些信息(目前的版本僅輸出操作用時(shí))
    • --extra - 開啟附加優(yōu)化,這些優(yōu)化并未得到全面的測(cè)試。
    • --unsafe - 開啟其他附加優(yōu)化,這些優(yōu)化已知在特定情況下并不安全,目前僅支持: 
        • foo.toString() ==> foo+”” 
    • --max-line-len (默認(rèn)32K字節(jié)) - 在32K字節(jié)出增加換行符,傳入0禁用此功能。
    • --reserved-names - 一些類庫(kù)會(huì)依賴一些變量,該參數(shù)指定的名稱不會(huì)被混淆掉,多個(gè)用逗號(hào)隔開。 

API

要想在Javascript中使用UglifyJS類庫(kù),參考下面的示例(以NodeJS為例):

var jsp =require("uglify-js").parser;var pro =require("uglify-js").uglify;var orig_code ="Javascript代碼";var ast = jsp.parse(orig_code);// 解析代碼返回初始的AST
ast = pro.ast_mangle(ast);// 獲取變量名稱打亂的AST
ast = pro.ast_squeeze(ast);// 獲取經(jīng)過(guò)壓縮優(yōu)化的ASTvar final_code = pro.gen_code(ast);// 壓縮后的代碼

上面的代碼會(huì)立刻進(jìn)行代碼的全面壓縮,正如你所看到的,這里經(jīng)歷了一系列的步驟,你可有省略某些步驟以滿足自己的需求。

這里的函數(shù)有一些參數(shù),我們做些介紹: 

    • jsp.parse(code, strict_semicolons) - 解析JS代碼并返回AST。strict_semicolons是可選的,默認(rèn)為false,當(dāng)傳入true,解析器會(huì)在預(yù)期為分號(hào)而實(shí)際沒找到的情況下拋出錯(cuò)誤。對(duì)于大多數(shù)JS代碼我們不需要那么做,但嚴(yán)格約束代碼很有益處。
    • pro.ast_mangle(ast, options) - 返回經(jīng)過(guò)變量和函數(shù)名稱混淆的AST,它支持以下選項(xiàng): 
        • toplevel - 混淆頂級(jí)作用域的變量和函數(shù)名稱(默認(rèn)不開啟)。
        • except - 指定不被壓縮的名稱的數(shù)組 
    • pro.ast_squeeze(ast, options) - 開啟深度優(yōu)化以降低代碼尺寸,返回新的AST,選項(xiàng)可以是一個(gè)hash,支持的參數(shù)有: 
        • make_seqs (默認(rèn)true) 將多個(gè)語(yǔ)句塊合并為一個(gè)。
        • dead_code (默認(rèn)true) 將刪除不被使用的代碼。 
    • pro.gen_code(ast, options) - 通過(guò)AST生成JS代碼。默認(rèn)輸出壓縮代碼,但可以通過(guò)調(diào)整選項(xiàng)參數(shù)獲得格式化的輸出。選項(xiàng)是可選的,如果傳入必須為對(duì)象,支持以下選項(xiàng): 
        • beautify: false - 如果希望得到格式化的輸出,傳入true
        • indent_start: 0 (僅當(dāng)beautify為true時(shí)有效) - 初始縮進(jìn)空格
        • indent_level: 4 (僅當(dāng)beautify為true時(shí)有效) - 縮進(jìn)級(jí)別,空格數(shù)量
        • quote_keys: false - 傳入true將會(huì)用引號(hào)引起所有文本對(duì)象的key
        • space_colon: false (僅當(dāng)beautify為true時(shí)有效) - 是否在冒號(hào)前保留空格
        • ascii_only: false - 傳入true則將編碼非ASCII字符到\uXXXX 

結(jié)語(yǔ)

UglifyJS在語(yǔ)法上與Google壓縮相似,在性能上是一流的,所以建議多多實(shí)踐!

 

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多