Usage
使用 command line 執行 Java jar file:
java -jar compiler.jar --指令
Main
-
--compilation_level :設定 compile 的等級,預設為 SIMPLE_COMPILATIONS
- SIMPLE_COMPILATIONS: 修改 locale variable
- ADVANCED_COMPILATIONS
EX:
--compilation_level SIMPLE_COMPILATIONS -
--js:要進行 compile 的 JavaScript file 路徑;可以使用
*一次添加複數檔案,或是!*排除複數檔案EX:
--js 'JS1.js' 'JS2.js'、--js 'JS1.js' --js 'JS2.js' -
--js_output_file:匯出的檔案名稱及路徑
EX:
--js_output_file 'compiledJS.js' -
--externs:引用的 library。設定此參數會排除 JavaScrip file 中外部檔案的 variables。
-
jQuery 必須使用 Google Closure Library 中提供的檔案
EX:
--externs './path/jquery-3.1.js' --externs './path/semantic-ui.js'
-
Other
-
--formatting:設定匯出檔案的格式
- PRETTY_PRINT:匯出的檔案斷行
EX:
--formatting PRETTY_PRINT -
--generate_exports:設定是否識別
/** @export */並將註記的 variable 作為 symbol 處理EX:
--generate_exports -
--force_inject_library:強制於匯出的 js 檔中加入指定名稱的 library
EX:
--force_inject_library es6_runtime:匯出的 js 檔中加入相容於 es6 的 polyfill library -
--isolation_mode:將匯出的程式包裹在 function 中 EX://Command 參數: //--compilation_level ADVANCED //--generate_exports true //--isolation_mode IIFE //Import /** @export */ class Citizen { constructor(name) { this.name = name; } /** @export */ sayHello(to) { let output = this.name + 'say: "Hello! "'+ to.name +'!'; console.log(output); } } //Export //NOTE: 為方便理解, 部分屬性名稱與實際輸出不同 function() { var global = this; function a (name) { this.name = name || ""; } a.prototype.a = function (a) { let output = this.name + 'say: "Hello! "'+ a.name +'!'; console.log(output); } a.prototype.sayHello = a.prototype.a; global["Citizen"] = a; }.call(this);
Feature
- 可以配合 JSDoc 註記協助 compile
/** @constructor *//** @extends *//** @override *//** @export */
- ES6會被 compile 為 ES5
ADVANCED_OPTIMIZATIONS
-
修改 local variable
-
修改 global variable
-
移除未被使用的 code
-
將部分 functions/variables 修改為 inline 呼叫的方式:
// Before function hello () {console.log("hello")}; hello(); // After console.log("hello"); -
若要避免 code 被修改,則需做 export 處理
Note
-
以
name作為 key 的話,key 不會被修改。//Before var customer = {name: "John"} window["customer"] = customer; //After var a= {name: "John"} window["customer"] = a;
Export
避免 API 被修改的方法
Solution 1: Export Symbols
Google Closure Compiler 進行編譯時不會修改 String
-
於作為 Symbol 的變數後在 global scope 以 String 重新宣告 variables:
var customer = { name: "Peter", gender: "male", hello: function () {console.log("hello " + this.name);} } window["customer"] = customer; customer["name"] = customer.name; customer["gender"] = customer.gender; customer["hello"] = customer.hello; customer.hello(); -
將變數中屬性的 key 以 String 表示:
var customer = { "name": "Peter", "gender": "male", "hello": function () {console.log("hello " + this["name"]);} } window["customer"] = customer; customer["hello"]();
Solution 2: /** @export */
增加指令 --generate_exports 並將 Google Closure Library 中的 base.js 設為 --js 'base.js' 'otherJavascript.js'
-
不支持 object 的 literal expression:
/** @export */ var customer = { name: "Peter", gender: "male", /** @export */ //error: @export only applies to symbols/properties defined in the global scope. hello: function () {console.log("hello " + this.name);} }要作為 Symbols 的 properties 必須各別宣告:
var customer = {} /** @export */ customer.name = "Peter"; /** @export */ customer.gender = "male"; /** @export */ customer.hello = function () {console.log("hello " + this.name)}; customer.hello(); -
ES6 將被編譯為 ES5:
/** @export */ class Customer { constructor() { this.nickName = "Arren"; /** @export */ //error: @export only applies to symbols/properties defined in the global scope. this.gender = "male" } /** @export */ hello () { console.log("hello" + this.name); } }
Compile 前後比較
-
Solution 1 - 以 String 重新宣告 variables:Before 276 字 | After 164 字
- 優點:現有 code 需要修改的範圍較小
- 缺點:每個元件 API 處皆須增加數行 variables 宣告,後續維護麻煩
-
Solution 1 - 屬性的 key 以 String 表示:Before 180 字 | After 129 字
- 優點:編譯後的字數最少
- 缺點:現有 API 的使用皆須改為
componentName["PROPERTY_NAME"]的方式,修改幅度較大
-
Solution 2 -
/** @export */:Before 198 字 | After 141 + 285 字- 285 字為重複使用的部分
- 優點:後續維護方便,僅需在註記的部分增加
@export關鍵字 - 缺點:若 library 為各部分獨立 compile,則每個檔案都會多出 285 字;且現有 literal 寫法必須修改