javascript下條件編譯的實現(基於webpack的js-conditional-compile-loader插件)

條件編譯,是指 用同一套代碼和同樣的編譯構建過程,根據設置的條件,選擇性地編譯指定的代碼,從而輸出不同程序的過程。一般用在C++、Java、C#這樣的編譯執行語言。對於javascript,我們也可以使用基於webpackjs-conditional-compile-loader插件實現類似的條件編譯功能。

我們經常會遇到類似這樣的需求:

  • 代碼需要根據運行環境,運行不同的代碼。比如,測試環境可以控制檯輸出一些信息,生產環境則不提示;同時又不希望輸出的代碼中存在判斷環境的if-else代碼使程序包體積增大。
  • 項目交付給多個客戶使用,而某些客戶會有一些定製模塊。這些定製模塊只給特定用戶使用,不希望也一起打包在不相干客戶的程序包中,但也不希望給定製客戶單獨維護一個特殊項目而增加維護成本。

使用條件編譯的方法,可以優雅地解決這樣的問題,同時代碼維護方便,發佈的程序包中也不會有多餘的代碼存在。

插件原理

js-conditional-compile-loader插件是一個webpack的loader插件,它會在webpack處理js代碼之前,將js代碼根據設置的條件進行修改,去掉當前條件下不需要的代碼,保留需要的代碼,從而實現條件編譯的功能。

使用步驟

可參考這裏的中文文檔

1. 安裝

npm i -D js-conditional-compile-loader

2. 配置webpack

在rules中爲js文件添加loader,作爲第一步處理js文件,並配置編譯條件。

module: {
    rules: [
        {
            test: /\.js$/,
            include: [resolve('src'), resolve('test')],
            use: [
                //step-2
                'babel-loader?cacheDirectory',
                //step-1
                {
                    loader: 'js-conditional-compile-loader',
                    options: {
                        isDebug: process.env.NODE_ENV === 'development', // optional, this is default
                        myFlag: process.env.ENV_COMPANY === 'ALI', // any name, used for /* IFTRUE_myFlag ...js code... FITRUE_myFlag */
                    }
                },
            ]
        },
        //other rules
    ]
}

3. 項目代碼中使用

插件支持IFDEBUG和IFTRUE兩個條件編譯指令。用法是:在js代碼的任意地方以/*IFDEBUG/*IFTRUE_xxx開頭,以FIDEBUG*/FITRUE_xxx*/結尾,中間是被包裹的js代碼。xxx是在webpack中指定的條件屬性名,如上面的myFlag。

舉個例子,我們用這樣的源代碼:

/* IFTRUE_forAlibaba */
var aliCode = require('./ali/alibaba-business.js')
aliCode.doSomething()
/* FITRUE_forAlibaba */

$state.go('win', {dir: menu.winId /*IFDEBUG , reload: true FIDEBUG*/})

當webpack中插件的options配置爲{isDebug: true, forAlibaba: true}時,構建後輸出的內容:

var aliCode = require('./ali/alibaba-business.js')
aliCode.doSomething()

$state.go('win', {dir: menu.winId, reload: true })

當webpack中插件的options配置爲{isDebug: false, forAlibaba: false}時,構建後輸出的內容爲:

$state.go('win', {dir: menu.winId})

如此便實現了條件編譯。結合命令參數關聯到環境變量,可以用命令參數指定不同的編譯條件。實際項目中可以按照你的需要盡情發揮。

這裏是個完整項目的例子,可供參考。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章