1. 场景

  • 已知webpack中存在一份默认配置文件,默认为webpack.config.js,其中可以通过plugins载入DefinePligin插件用于定义全局环境变量
  • 现在需要按照环境分为两种相同字段的配置以便区分测试环境对接的接口生产环境对接的接口,如下所示:
1
2
3
4
5
6
7
8
9
10
11
module.exports = {
...,
plugins: [
new webpack.DefinePlugin({
'process.env': {
BASE_API: JSON.stringify('http://localhost:8080')
}
}),
...
]
}

2. 解决方案

webpack官方帮助文档得知,如果想要按照不同的环境,加载不同的全局变量,可将默认的webpack.config.js拆分为webpack.dev.jswebpack.prod.jswebpack.common.js文件,再配合webpack-merge对差异化配置按照加载环境的不同进行配置合并,从而避免在原配置文件中进行大量冗余的三目运算符或者if-else,具体变更如下所示:

project

1
2
3
4
5
6
7
8
9
10
11
  webpack-demo
|- package.json
- |- webpack.config.js
+ |- webpack.common.js
+ |- webpack.dev.js
+ |- webpack.prod.js
|- /dist
|- /src
|- index.js
|- math.js
|- /node_modules

webpack.common.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: {
app: './src/index.js'
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Production'
})
],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

webpack.dev.js

1
2
3
4
5
6
7
8
9
10
11
12
13
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')

module.exports = merge(common, {
plugins: [
new webpack.DefinePlugin({
'process.env': {
BASE_API: JSON.stringify('http://localhost:8080')
}
})
]
})

webpack.prod.js

1
2
3
4
5
6
7
8
9
10
11
12
13
const merge = require('webpack-merge')
const common = require('./webpack.common.js')
const webpack = require('webpack')

module.exports = merge(common, {
plugins: [
new webpack.DefinePlugin({
'process.env': {
BASE_API: JSON.stringify('https://production:port')
}
})
]
})

最后,再通过启动命令webpack --config weboack.prod.js指定加载的默认配置文件,即可完成配置文件分离

3. 小贴士

  • 当遇到TypeError: merge is not a function

    • 检查webpack-mergewebpack的版本适配
    • 可尝试使用ES6解构赋值将const merge = require('webpack-merge')更改为const { merge } = require('webpack-merge')后重试
  • 为什么DefinePlugin插件里头的value需要用JSON.stringify()方法进行处理

    • 因为在全局变量中JSON.stringify(‘hello-world’)'hello-world'是不同的

      • 当使用JSON.stringify('hello-world')
      1
      if (hello === 'hello-world')
      • 当直接使用hello-world
      1
      if (hello === hello-world)