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

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

應用場景舉例

咱們常常會遇到相似這樣的需求:前端

  • 代碼須要根據運行環境,運行不一樣的代碼。好比,測試環境能夠控制檯輸出一些信息,生產環境則不提示;同時又不但願輸出的代碼中存在判斷環境的if-else代碼使程序包體積增大。
  • 項目交付給多個客戶使用,而某些客戶會有一些定製模塊。這些定製模塊只給特定用戶使用,不但願也一塊兒打包在不相干客戶的程序包中,但也不但願給定製客戶單獨維護一個特殊項目而增長維護成本。
  • 前端爲了調試,引用了不少mock數據。可是生產環境打包時也包含了這些mock數據和mock插件,增大了代碼包體積。但願生產環境程序包徹底不含這些(即便是異步按需加載也不要)。

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

插件原理

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

使用步驟

可參考這裏的中文文檔webpack

1. 安裝

npm i -D js-conditional-compile-loader

2. 配置webpack

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

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.npm_config_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。github

舉個例子,web

源碼:

咱們用這樣的源代碼:npm

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

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

條件1輸出

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

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

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

條件2輸出

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

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

如此便實現了條件編譯。結合命令參數關聯到環境變量,能夠用命令參數指定不一樣的編譯條件。例如本文中的配置條件:myFlag: process.env.npm_config_ali,執行命令時帶上--ali便可激活爲truenpm run build --ali
實際項目中能夠按照你的須要盡情發揮。

示例項目

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

相關文章
相關標籤/搜索