webpack.DefinePlugin使用介紹

滴滴出行·DDFE發表於2017-01-01

作者:滴滴公共前端團隊 - J

基本用法

這個外掛用來定義全域性變數,在webpack打包的時候會對這些變數做替換。
先看個例子

//webpack.config.js
var webpack = require('webpack');
var path = require('path');

module.exports = {
    entry: {
        index: "./js/index.js"
    },
    output: {
        path: "./dist/",
        filename: "js/[name].js",
        chunkFilename: "js/[name].js"
    },
    plugins: [
        new webpack.DefinePlugin({
            SOMETHINE: 'This is something we needed.'
        })
    ]
};

//index.js
console.log(SOMETHINE);複製程式碼

編譯完的結果如下:

function(module, exports, __webpack_require__) {
   console.log((This Is The Test Text.));
}複製程式碼

可以看到程式碼中 SOMETHINE 被直接替換為 This is something we needed. 但是我們的本意中 SOMETHINE 是一個字串,而直接替換後卻不是一個字串。怎麼辦呢?

方法一:可以將 SOMETHINE 的值寫成

SOMETHINE: '"This is something we needed."'複製程式碼

方法二: 藉助 JSON.tringify ,轉為字串

SOMETHINE: JSON.stringify('This is something we needed.')複製程式碼

推薦使用方法二,它不僅可以處理字串,還可以處理Object中的字串和Array。如下:

//webpack.config.js

 plugins: [
    new webpack.DefinePlugin({
        OBJ: JSON.stringify({"key1": "this is value"}),
        OBJ2: {"key1": "this is value"},
        OBJ3: {"key1": "'this is value'"},
        ARRAY: JSON.stringify(["value1", "value2"]),
        ARRAY2: ["value1", "value2"],
        ARRAY3: ["'value1'", "'value2'"]
    })
]

//index.js
console.log(OBJ);
console.log(OBJ2);
console.log(OBJ3);
console.log(ARRAY);
console.log(ARRAY2);
console.log(ARRAY3);複製程式碼

編譯結果

console.log(({"key1":"this is value"})); // OBJ 正確
console.log(({"key1":this is value})); // OBJ2 this is value 被直接替換了,而非字串
console.log(({"key1":'this is value'})); // OBJ3 正確
console.log((["value1","value2"])); // ARRAY 正確
console.log(({"0":value1,"1":value2})); // ARRAY2 直接寫[]的形式,會被替換為object的型別,value1 和 value2 不是字串
console.log(({"0":'value1',"1":'value2'})); // ARRAY3 正確複製程式碼

還剩下 Number 和 Boolean 兩種變數型別,對於這兩種型別,就不像上面介紹的這麼麻煩了,直接寫就行

//webpack.config.js

 plugins: [
    new webpack.DefinePlugin({
        NUMBER: 12,
        BOOL: true
    })
]

//index.js
console.log(NUMBER);
console.log(BOOL);複製程式碼

編譯結果

console.log((12));
console.log((true));複製程式碼
實際運用

介紹了這麼多,在實際使用中, DefinePlugin 最為常用的用途就是用來處理我們開發環境和生產環境的不同。比如一些 debug 的功能在生產環境中需要關閉、開發環境中和生產環境中 api 地址的不同。以 vue-cli 生成的打包檔案為例子,來看看在實際中的使用。

vue-cli 生成的目錄中編譯、打包相關的有兩個資料夾 build 和 config 。

build 資料夾中找到 wbepack.dev.conf.js 和 webpack.prod.conf.js ,這兩個檔案中都通過 DefinePlugin 外掛定義了 process.env 這個變數

// webpack.dev.conf.js
var config = require('../config')
...
new webpack.DefinePlugin({
  'process.env': config.dev.env
})

// webpack.prod.conf.js
var config = require('../config')
var env = config.build.env
...
new webpack.DefinePlugin({
  'process.env': env
})複製程式碼

config 中對 env 的定義分別放在 config/dev.env.js 和 config/prod.env.js 中

//config/index.js
module.exports = {
  build: {
    env: require('./prod.env'),
    ...
  },
  dev: {
    env: require('./dev.env'),
    ...
  }
}

//config/prod.env.js
module.exports = {
  NODE_ENV: '"production"'
}

//config/dev.env.js
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})複製程式碼

到此可以看到,在 wbepack.dev.conf.js 中最終為

'process.env': {NODE_ENV: '"development"'}複製程式碼

在 webpack.prod.conf.js 中最終為

'process.env': {NODE_ENV: '"production"'}複製程式碼

在我們的程式碼中,如果部分只是在開發環境下才執行的邏輯,那麼可以通過下面的方式

if ('development' === process.env.NODE_ENV) {
 // 開發環境下的邏輯
} else {
 // 生產環境下
}複製程式碼

歡迎關注DDFE
GITHUB:github.com/DDFE
微信公眾號:微信搜尋公眾號“DDFE”或掃描下面的二維碼

webpack.DefinePlugin使用介紹

相關文章