在项目构建时不同的环境下会有不同配置,在前面文章中已经使用webpack5配置好了基础环境和开发环境,但是在生产环境时有些配置和开发环境是不需要的,有些是可以在优化的,所以下面继续生产环境的配置。
1、添加生产环境基础配置
首先我们需要在已经创建好的文件webpack.prod.js进行生产环境独有的配置,然后在引入生产环境和开发环境公用的基础配置。
修改webpack.prod.js文件,添加生产环境的基础配置
// webpack.prod.js
const { resolve } = require('./tools');
const { merge } = require('webpack-merge'); // 引入合并方法
const baseConfig = require('./webpack.base'); // 引入基础配置
module.exports = merge(baseConfig, {
mode: 'production', // 设置模式为production
})
然后修改package.json文件下的build打包指令,将生产环境打包文件指向config/webpack.prod.js
// package.json
"scripts": {
"build": "webpack --config config/webpack.prod.js",
},
执行 npm run build 命令打包,此时react-refresh/babel会报错因为热更新插件在生产环境的时候应该禁用,所以我们先把他注释掉在执行打包命令,此时最最基础的生产环境配置就完成了。
2、安装Live Server 插件查看效果
上面完成了生产环境最基础的配置,也成功打包,但是不知道打包后的代码在加载的时候是不是有问题,所以需要借助第三方的服务插件查看打包后的页面效果
在vscode插件商店安装Live Server 插件
然后修改Live Server 的root地址为dist,这样我们就可以直接加载打包后的资源
修改好配置后,鼠标右键选择index.html文件选择使用Live Server打开此时就可以直接查看打包效果
3、添加环境变量
在打包的时候我们需要区分开发环境和生产环境(如上面热更新插件的使用),在不通用的配置下我们可以通过配置文件的拆分实现,在通用配置的时候我们就需要在执行打包命令时注入来实现
使用 cross-env 依赖库来注入环境变量,安装cross-env
npm i cross-env -D
修改package.json 文件下打包指令
// package.json
"scripts": {
"build": "cross-env NODE_ENV=production webpack --config config/webpack.prod.js",
"dev": "cross-env NODE_ENV=development webpack-dev-server -c config/webpack.dev.js"
},
然后在webpack.base.js 文件下添加打印
console.log(process.env.NODE_ENV, 1111111111);
分别执行npm run build 和npm run dev查看变量打印的值
上面成功注入了在打包过程中环境变量,有时候我们的项目也需要业务中全局变量这个时候可以使用webpack中DefinePlugin插件实现
修改webpack.base.js 文件增加业务中全局变量插件配置
// webpack.base.js
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.DefinePlugin({ // 调用插件
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),
]
}
4、根据变量配置插件
添加完环境变量后首先根据环境变量去处理不同插件和loader的配置
首先提取出一个判断生产环境的函数,修改config/tools.js文件
// tools.js
function isProd() {
return process.env.NODE_ENV === 'production';
}
module.exports = {
isProd
};
修改babel.config.js文件根据变量处理热更新插件
// babel.config.js
const { isProd } = require('./config/tools');
module.exports = {
plugins: [
!isProd() && require.resolve('react-refresh/babel')
].filter(Boolean)
}
此时在执行npm run build指令进行打包正常不在报错。
在开发环境我们处理css文件时使用style-loader将解析后的css插入到head标签中进行加载方便调试和样式热替换,在生产环境中我们会将css抽离出单独的文件资源并引入使用可以利用缓存配置。下面使用mini-css-extract-plugin插件完成
// 安装
npm i mini-css-extract-plugin -D
修改webpack.base.js文件,生产环境下使用mini-css-extract-plugin插件loader开发环境下还使用style-loader
// webpack.base.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 引入抽离css插件
const { isProd } = require('./tools');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [
// 生产环境下使用MiniCssExtractPlugin.loader
isProd() ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
]
},
// 当使用多个loader处理模块时,use为数组格式,并且loader的执行顺序为从下到上,从后往前。
{
test: /\.less$/,
use: [
isProd() ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'less-loader'
],
include: resolve("src"),
},
]
},
}
修改webpack.prod.js文件,进行mini-css-extract-plugin插件调用并设置抽离出css文件名等
// webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // 引入抽离css插件
module.exports = merge(baseConfig, {
plugins: [
// 调用抽离插件
new MiniCssExtractPlugin({
// 抽离后的资源名称和存放路径
filename: 'static/css/[name].[contenthash:8].css',
// 非入口的 chunk 文件名称
chunkFilename: 'static/css/[name].[contenthash:8].css',
})
]
})
执行npm run build 打包命令,查看live-server上的项目效果
5、代码压缩
上面css代码已经被抽离出单独文件并且以资源的方式日引入使用,但是这时候我们看dist目录下已经打包好的css文件里面的内容没有被压缩还是正常展示,在生产环境上加载资源的大小也影响加载性能。下面我们使用css-minimizer-webpack-plugin插件进行压缩css文件(也可以使用optimize-css-assets-webpack-plugin)
安装
npm install css-minimizer-webpack-plugin --save-dev
修改webpack.prod.js文件,进行css-minimizer-webpack-plugin插件的调用
// webpack.prod.js
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin"); // 引入css压缩插件
module.exports = merge(baseConfig, {
optimization: {
minimizer: [
new CssMinimizerPlugin(),
],
},
})
然后执行npm run build打包命令,查看打包后的css文件是否压缩和页面是否加载正常
css代码成功压缩后,下面来配置js代码压缩,其实当webpack设置模式为production时js文件的代码会自动进行压缩,但是因为我们上面配置optimization.minimizer后这个压缩就失效了,所以需要我们再次安装terser-webpack-plugin插件调用即可
npm install terser-webpack-plugin --save-dev
修改webpack.prod.js文件,调用terser-webpack-plugin插件
// webpack.prod.js
const TerserPlugin = require("terser-webpack-plugin"); // 引入js压缩插件
module.exports = merge(baseConfig, {
optimization: {
minimizer: [
new TerserPlugin({
// 传入删除注释配置
terserOptions: {
format: {
comments: false,
},
},
extractComments: false,
})
],
},
})
再次执行npm run build命令查看打包后的文件和页面效果是否正常即可。
使用webpack5配置react的生产环境的基础也完成了,但是还有许多可以优化的细节,后面继续将可以优化的地方加进来。