在使用Webpack自定义构建项目的脚手架的时候,我们常常会使用到mini-css-extract-plugin这个插件来将css代码提取出来构建成单独的一个css文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: '[name].css',
chunkFilename: '[id].css',
}),
],
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
// only enable hot in development
hmr: process.env.NODE_ENV === 'development',
// if hmr does not work, this is a forceful method.
reloadAll: true,
},
},
'css-loader',
],
},
],
},
};

以上为官方文档给出的方法,但在实际的运用中并不能实现热重载。

在搜索引擎中寻找后,我也没有发现行之有效的方法,但我又想了想,既然是开发环境的热重载,那就没必要将css代码抽离出来呀,于是我的方法想到了:判断当前环境是否为开发环境,如果是,就不使用mini-css-extract-plugin这个插件,而是使用最原始的style-loader来将css代码构建到style标签里。而生产环境,则使用mini-css-extract-plugin插件来抽离css代码。

根据这个思路,我写出了如下的构建相关代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [
process.env.NODE_ENV === 'development'
? 'style-loader'
: MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader',
'less-loader'
]
},
...
]
},
plugins: [
...
new MiniCssExtractPlugin({
filename: '[name].[contenthash:8].css',
chunkFilename: '[id].css'
})
...
]
}

在一般环境下,用作区别开发和生产环境的变量process.env.NODE_ENV是不会自己赋值的,因此我们需要在package.json里的相关运行命令中添加生产环境变量:

1
2
3
4
5
6
{
"scripts": {
"dev": "NODE_ENV=development webpack-dev-server --hot --config ./build/webpack.dev.config.js --color --progress",
"build": "NODE_ENV=production webpack --config ./build/webpack.prod.config.js --color --progress"
},
}

这样写的话,Linux和Mac电脑都可以正常构建,但windows会报如下错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
'NODE_ENV' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

npm ERR! Windows_NT 6.1.7601
npm ERR! argv "D:\\nodejs\\node.exe" "D:\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "start"
npm ERR! node v4.0.0-rc.5
npm ERR! npm v2.14.2
npm ERR! code ELIFECYCLE
npm ERR! yy-ydh-web@1.0.7 start: `npm run clear&& NODE_ENV=development && webpack-dev-server --host 0.0.0.0 --devtool ev
al --progress --color --profile`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the yy-ydh-web@1.0.7 start script 'npm run clear&& NODE_ENV=development && webpack-dev-server --host
0.0.0.0 --devtool eval --progress --color --profile'.
npm ERR! This is most likely a problem with the yy-ydh-web package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! npm run clear&& NODE_ENV=development && webpack-dev-server --host 0.0.0.0 --devtool eval --progress --color
--profile
npm ERR! You can get their info via:
npm ERR! npm owner ls yy-ydh-web
npm ERR! There is likely additional logging output above.

搜索后发现是Windows系统不兼容这种写法,因此我们需要使用cross-env来设置运行跨平台设置和使用环境变量的脚本,于是,package.json代码更改如下:

1
2
3
4
5
6
{
"scripts": {
"dev": "cross-env NODE_ENV=development webpack-dev-server --hot --config ./build/webpack.dev.config.js --color --progress",
"build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.config.js --color --progress"
}
}

更改后再yarn dev或者yarn build,我们会发现已经可以实现根据生产环境或者开发环境来选择适当的构建配置了,这个时候已经可以实现开发环境的css代码热重载了。