フロントエンドスクリプトの圧縮-UglifyJS2
Front End Script Compression Uglifyjs2
簡単な例
//steps-01: install dependencies npm install uglify-js //steps-02: development now //index.js //steps-03: set the command //steps-04: Run the command
クラスライブラリの紹介
UglifyJSは、JavaScriptで記述されたJavaScriptコンプレッサー/ミニファイアです。また、JavaScriptコードの操作を自動化できるツールも含まれています。
コード分析:A パーサー これは、 抽象構文木(AST) JavaScriptコードから。
コード生成:A コードジェネレーター ASTからJavaScriptコードを出力し、取得するオプションも提供します ソースマップ 。
コード圧縮:A コンプレッサー(オプティマイザー) —トランスフォーマーAPIを使用して、ASTをより小さなものに最適化します。
スコープ:A スコープアナライザー 、変数が定義/参照される場所などに関する情報でASTを拡張するツールです。
生の現地数量:* A 行方不明 —ローカル変数の名前を(通常は)1文字に減らします。
インストール
//Global npm install uglify-js -g //local npm install uglify-js --save-dev
コマンドラインで
Syntax: uglifyjs [input files] [options] Simple example: uglifyjs --compress --mangle -- input.js Example of parameters: View version: uglifyjs --version View help: uglifyjs --help About parsing: --parse About compression: --compress About confusion: --mangle About beautification: 。。。
インターフェイスリファレンス
リソースマッピング
UglifyJS2はソースマップファイルを生成できます。これは、圧縮されたJSコードのデバッグに非常に役立ちます。
美化について
デフォルトでは、コードジェネレーターは可能な限り短いコードを出力します。出力コードを美化したい場合は、-beautify(-b)を設定してください。より多くのオプションオプション引数を渡すことで、より多くのコード生成を制御できます。
Beautify(デフォルトはtrue)-Whether it is beautifying
出力コード。 -bを渡すとtrueに設定されます。最小限のコードを生成し、他の設定を使用してコードを美化したい場合は、-b beautify = falseを設定できます。
インデントレベル(デフォルトは4)-Indented number
インデント開始(デフォルトは0)-各行の前にいくつかのスペースを追加します-Pre-row space
引用キー(デフォルトはfalse)-オブジェクトのKey bracket
space-colon(デフォルトはtrue)-コロンの後にスペースを追加します-Space after
ascii-only(デフォルトはfalse)-Unicode文字が文字列/正規文字に表示されないようにします(非ASCII文字は無効になります)。
インラインスクリプト(デフォルトはfalse)-スラッシュを避けるwidth(デフォルトは80)-線幅を設定します。
max-line-len(デフォルトは32000)-最大線幅(圧縮コード)
ブラケット化(デフォルトはfalse)-ループ本体に文が1つしかない場合でも、if、for、do、while、withの後に常に中括弧を追加します。 -Inline script
セミコロン(デフォルトはtrue)-複数の宣言をセミコロンで区切ります。 falseを渡すと、出力ファイルの可読性を高めるために常に別の行があります。 (gzipが小さくなる前、gzipの後は少し大きくなります)-Increment
プリアンブル(デフォルトはnull)-渡される場合は文字列である必要があります。出力ドキュメントの前に追加されます。ソースマップはそれに応じて調整されます。たとえば、Variable declaration
を挿入するために使用できます。
quote_style(デフォルトは0)-文字列に影響しますCopyright Information
(プロパティ名とディレクティブにも影響します)。
0-二重引用符を使用する傾向があり、文字列内の引用符は一重引用符です。
1-常に一重引用符
2-常に二重引用符
3-常に元の引用符
keep_quoted_props(デフォルトはfalse)-有効にすると、属性名の引用符が保持されます。
圧縮について
渡されるBracket format
圧縮を有効にする。あなたはそれを使うことができます--compress (-c)
別々のオプション。オプションの形式はcomma
または単にfoo=bar
(後者はtrueに設定する略語に相当し、foo = trueに相当します)。
foo
(デフォルトはtrue)-変数をコンマで区切って連続して宣言します。正の整数を設定して、連続する宣言の最大長を指定できます。設定されている場合sequences
デフォルトを示しますtrue
設定200
またはfalse
次に無効にします。0
少なくともsequences
、2
同じ1
istrue
)。デフォルトのシーケンス設定では、圧縮が遅くなる可能性が非常に低いため、200
以下に設定することをお勧めします。 -20
Declare variable
--useproperties
プロパティ参照をオーバーライドするには、たとえば.
。——foo['bar'] → foo.bar
Property rewriting
-参照されていないコードを削除します。 -dead_code
Remove code
-削除drop_debugger
debugger
(デフォルトはfalse)-「安全でない」変換を使用します(以下で詳しく説明します)unsafe
(デフォルトはfalse)-keepunsafe_comps
と<
置き換えられません<=
>
で。一部のコンピューティングオブジェクトが使用されている場合>=
またはget
オブジェクトが派生すると、変換が安全でなくなり、オペランドが変更される可能性があります。このオプションは、valueOf
withcomparisons
の場合にのみ使用できます。 trueに設定されている場合にのみ有効になります。unsafe_comps
(デフォルトはfalse)-たとえば、数式を最適化しますunsafe_math
2 * x * 3
になると、浮動小数点の結果が不正確になる可能性があります。 -6 * x
Digital expression (not recommended)
(デフォルトはfalse)-putunsafe_proto
最適化Array.prototype.slice.call(a)
-[].slice.call(a)
Array expression
-最適化conditionals
判断と条件の選択-if
Conditional expression
-結果の必然的な結果を二項演算に最適化します。例:comparisons
(設定のみ!(a <= b) → a> b
有効のみ)操作なしに変えてみてください。例:unsafe_comps
-a = !b && !c && !d && !e → a=!(b||c||d||e)
Operational expression (not recommended)
-定数式を計算してみてください-evaluate
Constant expression (not recommended)
-booleans
-!!a? b : c → a ? b : c
などのブール演算を最適化しますBoolean expression (not recommended)
-いつloops
、do
、while
ループの判定条件はであると判断でき、最適化されます。for
-参照されていない関数と変数を強制終了します。 (設定されていない限りunused
そうでない場合、変数の単純な直接割り当ては考慮されません。)-'keep_assign'
Code culling
-最上位スコープ(toplevel
)および/または変数('funcs'
)で参照されていない関数を強制終了します(デフォルトは'vars'
、false
関数変数の場合殺されたら-true
Code culling
-設定時top_retain
最上位スコープでいくつかの関数変数を予約した場合。 (配列として、コンマで区切って、または通常または関数を使用して記述できます。unused
)-toplevel
Code culling
-リフト関数宣言hoist_funs
(デフォルトはfalse)-プロモーションhoist_vars
ステートメント(デフォルトはvar
ファイルのサイズが大きくなるため)false
--if / returnおよびif / continueを最適化しますif_return
-継続的に統合join_vars
ステートメント-var
Declare variable
-連続ステートメントを弱く最適化します、willcascade
変換x, x
、x
変換x = something(), x
-x = something()
Declare variable
-collapse_vars
の場合var
で単独で使用する場合はマージしてみてください-const
Declare variable
-特定の変数が実際に割り当てられ、定数値として使用される場合を最適化します。reduce_vars
-役に立たないコードを削除するときに警告を表示します-warnings
Code culling
-役に立たない場合は、即時実行関数(IIFE)の戻り値をキャンセルします。コードジェネレーターが括弧を挿入することは避けてください。negate_iife
-デフォルトはpure_getters
渡すとfalse
、UglifyJSはオブジェクトプロパティへの参照を想定します(たとえば、true
またはfoo.bar
関数の副作用はありません。foo['bar']
--defaultpure_funcs
名前の配列を渡すことができ、UglifyJSはこれらの関数に関数の副作用がないと想定します。 警告: 名前がスコープで再定義された場合、その名前は再度検出されません。例null
変数var q = Math.floor(a/b)
参照されていない場合、UglifyJSはそれを強制終了しますが、q
保持され、誰もそれが何をしているのかわかりません。関数に副作用がないと見なされるようにMath.floor(a/b)
を設定して、宣言全体を破棄することができます。現在の実装では、オーバーヘッドが増加します(圧縮が遅くなります)。pure_funcs: [ 'Math.floor' ]
-デフォルトdrop_console
合格false
強制終了true
関数。console.*
のような特定の関数を強制終了する場合そして、削除後にパラメータの副作用を削除したい場合は、console.info
を使用して対処しましょう。 -pure_funcs
Code culling
-デフォルトexpression
。 passfalse
ターミナルステートメントで「return」の完了値を保持します。たとえば、ブックマークレットで。true
-デフォルトkeep_fargs
。コンプレッサーが使用されていない関数パラメーターを強制終了しないようにします。いくつかの依存関係を保護するために必要ですtrue
関数。 -Function.length
Code culling
-デフォルトkeep_fnames
。 Passfalse
コンプレッサーが関数名を強制終了しないようにします。それらの依存関係についてtrue
この関数は非常に便利です。 -Function.prototype.name
Code culling
-デフォルトpasses
。圧縮が実行された回数。場合によっては、1より大きい数値パラメーターを使用してコードサイズをさらに圧縮できます。注:数値が大きいほど、圧縮にかかる時間が長くなります。1
-デフォルトkeep_infinity
。 passfalse
put時の圧縮を防ぐためtrue
transform1/0
chromeでパフォーマンスの問題が発生する可能性があります。
混乱について
難読化機能を有効にするには、Infinity
を渡す必要があります。サポート--mangle (-m)
個別のオプション。
いくつかの言葉を残す
混乱することなくいくつかの名前を保持したい場合は、-reserved(-r)を使用して、コンマで区切っていくつかの名前を宣言できます。
comma
条件付きコンパイル
Uglifyは、グローバル変数が定数であると想定しています(ローカルドメインで定義されているかどうかに関係なく)、-define(-d)を使用してグローバル変数を定義できます。
uglifyjs ... -m -r '$,require,exports'
特別トピック
その構造ツリー
そのパーサー(コード解析)
パーサーはカスタムを作成します 抽象構文木 JavaScriptコードの一部が与えられました。おそらくあなたはについて読むべきです AST 最初。
//Method 1: //steps-01: write code //condition-test.js if (DEBUG) { console.log('debug stuff') } //steps-02: Run the command uglifyjs condition-test.js --define DEBUG=false //Mode 2: //steps-01: write code //condition-test.js if (DEBUG) { console.log('debug stuff') } //steps-02: define variables //build/defines.js const DEBUG = false //... //steps-03: Run the command uglifyjs build/defines.js condition-test.js //Mode 3: //steps-01: write code //condition-test.js if (DEBUG) { console.log('debug stuff') } //steps-02: compression script //build/mini.js uglifyJS.minify([ 'input.js'], { compress: { dead_code: true, global_defs: { DEBUG: false } } }) //steps-03: Run the command node build/mini.js
いいえの場合// it takes the source code to parse as first argument: var ast = UglifyJS.parse('function sum(x, y){ return x + y }') // optionally you can pass another argument with options: var ast = UglifyJS.parse(code, { strict : true, // default is false filename : 'Input file name', // default is null toplevel : ast // also null })
引数が与えられると、パーサーはtoplevel
を作成しますノードを作成し、コードのすべてのステートメントをその本体に配置します。ただし、適切なAST_Toplevel
を生成するには複数のファイルを単一のトップレベルノードに解析する機能があると便利でした。これを行うには、次のように言います。-source map
、Multiple files
Resource mapping
そのジェネレーター(コード生成)
コードジェネレーターは、パーサーによって返されたASTからソースコードを取得する再帰的なプロセスです。
//Write 1: var ast = UglifyJS.parse(file1_content, { filename: 'file1.js' }) ast = UglifyJS.parse(file2_content, { filename: 'file2.js', toplevel: ast }) ast = UglifyJS.parse(file3_content, { filename: 'file3.js', toplevel: ast }) //Writing 2: // or in general, if in `files` array you have the list of files: var ast = null files.forEach(function(file){ var code = fs.readFileSync(file, 'utf8') ast = UglifyJS.parse(code, { filename: file, ast: ast }) })
すべて ASTノード
var stream = UglifyJS.OutputStream({ ...options... }) var code = ast.print(stream) console.log(stream.toString())
を取る「print」メソッドがありますそのノードからそのノードにコードをダンプします
OutputStream
ストリームオブジェクトは、出力を制御する多くのオプションをサポートしています。
リソースマッピング
出力ストリームは、出力内の現在の行/列を追跡し、Mozillaを介して元のコードへのソースマッピングを簡単に生成できます。 ソースマップ 図書館。この機能を使用するには、このライブラリをロードする必要があります(NodeJSバージョンのUglifyJSでは自動的に必要です-d
indent_start : 0, // start indentation on every line (only when `beautify`) indent_level : 4, // indentation level (only when `beautify`) quote_keys : false, // quote all keys in object literals? space_colon : true, // add a space after colon signs? ascii_only : false, // output ASCII-safe? (encodes Unicode characters as ASCII) inline_script : false, // escape 'コメントを残す
コードジェネレーターは、出力に特定のコメントを保持できます。
var source_map_options = { file : null, // the compressed file name root : null, // the root URL to the original sources orig : null, // the input source map } var source_map = UglifyJS.SourceMap({ source_map_options }) var stream = UglifyJS.OutputStream({ ... source_map: source_map }) ast.print(stream) var code = stream.toString() var map = source_map.toString() // json output for your source map
そのコンプレッサー(コード圧縮)
コンプレッサーは ツリートランスフォーマー これは、ASTにさまざまな最適化を適用することにより、コードサイズを削減します。
function(node, comment) { var text = comment.value var type = comment.type if (type == 'comment2') @license }
その命名装置(現地金額)
UglifyJSは、ローカル変数と関数の名前を通常は1文字に減らすことができます
var compressor_options = { sequences : true, // join consecutive statemets with the “comma operator” properties : true, // optimize property access: a['foo'] → a.foo dead_code : true, // discard unreachable code drop_debugger : true, // discard “debugger” statements unsafe : false, // some unsafe optimizations (see below) conditionals : true, // optimize if-s and conditional expressions comparisons : true, // optimize comparisons evaluate : true, // evaluate constant expressions booleans : true, // optimize boolean expressions loops : true, // optimize loops unused : true, // drop unused variables/functions hoist_funs : true, // hoist function declarations hoist_vars : false, // hoist variable declarations if_return : true, // optimize if-s followed by return/continue join_vars : true, // join var declarations cascade : true, // try to cascade `right` into `left` in sequences side_effects : true, // drop side-effect-free statements warnings : true, // warn about potentially dangerous optimizations/code global_defs : {} // global definitions } ast = UglifyJS.parse(code) ast.figure_out_scope() compressor = UglifyJS.Compressor({ compressor_options}) ast = ast.transform(compressor) code = ast.print_to_string() // get compressed code
そのアナライザー(分析範囲)
UglifyJSには、変数/関数の定義、参照などを把握するスコープアナライザーが含まれています。圧縮またはマングリングの前に手動で呼び出す必要があります。
ast = UglifyJS.parse(code) // compressor needs figure_out_scope too ast.figure_out_scope() compressor = UglifyJS.Compressor() ast = ast.transform(compressor) // need to figure out scope again so mangler works optimally ast.figure_out_scope() ast.compute_char_frequency() ast.mangle_names() // get Ugly code back :) code = ast.print_to_string()
ポスト方式
toplevel.figure_out_scope()
を呼び出した後、いくつかのメソッドが意味のあることを行います。
- AST_Scope :: find_variable(name)—変数を名前で検索し、見つかった場合は関連する変数を返します SymbolDef 。
- AST_Scope :: reference(def)—このスコープが指定されたSymbolDefを参照している場合、null以外を返します。
- AST_Symbol :: unmangleable()—
figure_out_scope
を返しますこのシンボルの名前を変更できない場合(グローバル、宣言されていない、またはtrue
またはeval
が使用されているスコープで定義されている。 - AST_Symbol :: unreferenced()—
with
を返しますこの記号が参照されていない場合。 - AST_Symbol :: undeclared()—
true
を返しますこのシンボルが宣言されていない場合。 - AST_Symbol :: global()—
true
を返しますこのシンボルがグローバル(トップレベル)スコープで定義されている場合。 - AST_Symbol :: defined()—関連付けられたを返します SymbolDef このシンボルのために。
射出特性
figure_out_scopeは、ノードに追加情報を追加します。
AST_Scopeノード内
- ディレクティブ—このスコープに表示されるディレクティブの配列。
- 変数—名前からへのマッピング SymbolDef 関数を含む、このスコープ内のすべての定義のオブジェクト。
- 関数—変数に似ていますが、関数宣言専用です。
- used_with —
true
になりますtrue
の場合ステートメントは、このスコープまたは任意のサブスコープで使用されます。 - used_eval —
with
になりますグローバルへの直接呼び出しの場合true
このスコープまたは任意のサブスコープに表示されます。 - parent_scope —親スコープへのポインター、またはこれのnullがトップレベルスコープです。
- 同封—のリスト SymbolDef -sこれまたはこれまたは内部スコープから使用される外部スコープで定義されます。
AST_Symbolノード内
- スコープ—へのポインタ 電流 範囲。
- thedef —へのポインタ SymbolDef このシンボルに関連付けられています
AST_LabelRefノード内
- スコープ—へのポインタ 電流 範囲。
- thedef —このシンボルが参照するAST_Label宣言へのポインタ
タグの定義
解析後、eval
を呼び出します。 ASTで追加情報を提供するため。この関数は、シンボルごとに一意の定義を作成します。
toplevel.figure_out_scope()
関連資料
https://segmentfault.com/a/1190000008995453
http://lisperator.net/uglifyjs/