webpack5不同环境配置拆分
webpack在不同环境下需要做些不同的配置,比如我们生产环境不需要压缩css和js,不需要devServer等,所以我们需要做区分
环境变量
问题1:怎么在webpack.config.js中获取env的值呢
module.exports可以等于一个函数,函数接收env这个参数,就可以得到值了
module.exports=(evn)=>{
return{
console.log(env)
}
}
问题2:怎么配置环境变量的值呢
第一种是在打包命令后加 例如:
npx webpack --env production
他在打包的时候就有相关信息:{ WEBPACK_BUNDLE: true, WEBPACK_BUILD: true, production: true
第二种实在webpack配置文件中加:
mode:"development"
第三种是在package.json的script脚本中添加 --env development
"dev": "webpack server --env development",
生产环境中可能会遇到这个打包的警告:
WARNING in entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (244 KiB). This can
impact web performance.
解决方法:
performance: {
hints: false,
},
npm配置修改
因为上面每次都要出入一长串的命令,不太方便,所以我们进行npm 的 script配置,
默认执行webpack.config.js文件,所以需要添加 -c 修改配置文件
"scripts": {
"dev": "webpack serve -c ./config/webpack.config.dev.js",
"build": "webpack -c ./config/webpack.config.prod.js"
}
npm run dev会执行./config/webpack.config.dev.js文件(npx webpack serve 就等于 npx webpack-dev-server )
npm run build就相当于执行了 npx webpack -c ./config/webpack.config.prod.js
拆分环境
那么我们怎么拆分呢?
这是我们的一个没做区分的配置文件
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const json5 = require("json5");
const { env } = require("process");
module.exports = {
entry: {
index: "./src/index.js",
es6: "./src/es6.js",
sameJs: "/src/sameModule.js",
},
output: {
filename: "[name].js",
// filename: "bundle.js",
// path: path.require(__dirname, "public"),
path: path.resolve(__dirname, "../dist"),
clean: true,
assetModuleFilename: "images/[contenthash][ext]",
publicPath: "http://localhost:8080/",
},
mode: env.production ? "production" : "development",
devtool: "inline-source-map",
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html",
inject: "body",
}),
new MiniCssExtractPlugin({
filename: "styles/[contenthash].css",
}),
],
devServer: {
static: "./dist",
},
module: {
rules: [
{
test: /\.jpg$/,
type: "asset/resource",
generator: {
filename: "images/[contenthash][ext]",
},
},
{
test: /\.(css|less)$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: [["@babel/plugin-transform-runtime"]],
},
},
},
{
test: /\.json5$/,
type: "json",
parser: {
parse: json5.parse,
},
},
],
},
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
};
第一种最容易想到的是在webpack.config.js中,根据env参数的值做不同的配置;但是这样不好阅读,不好维护,不优雅
第二种是写多个配置文件,不同的命令下执行不同的配置文件;但是这样会产生很多重复的代码
新建config文件夹,然后创建两个文件,分别用于开发环境的配置和生产环境的配置
webpack.config.dev.js:去除了代码压缩,缓存等
webpack.config.prod.js 去除了devServer等
输入不同的命令,执行不同的文件,就可以实现不同环境打包的不同了
直接输入打包命令:
npx webpack -c ./config/webpack.config.dev.js
npx webpack -c ./config/webpack.config.prod.js
通过命令:
"scripts": {
"dev": "npx webpack server -c ./config/webpack.config.dev.js",
"build": "npx webpack -c ./config/webpack.config.prod.js"
}
第三种就是第一种和第二种的升级,利用webpack-merge来拆分配置,最后根据不同环境合并配置
接下来的内容都是如何实现第三种拆分的:
配置拆分 – 实现执行不同命令,使用不同环境的配置
1》提取公共配置
不想要太多重复的代码,所以我们对他们进行合并
webpack.config.common.js
npm i webpack-merge -D
webpack.config.common.js文件:将开发环境和生产环境相同配置放在该文件中
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const json5 = require("json5");
module.exports = {
entry: {
index: "./src/index.js",
es6: "./src/es6.js",
sameJs: "/src/sameModule.js",
},
output: {
path: path.resolve(__dirname, "../dist"),
clean: true,
assetModuleFilename: "images/[contenthash][ext]",
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html",
filename: "index.html",
inject: "body",
}),
new MiniCssExtractPlugin({
filename: "styles/[contenthash].css",
}),
],
module: {
rules: [
{
test: /\.jpg$/,
type: "asset/resource",
generator: {
filename: "images/[contenthash][ext]",
},
},
{
test: /\.(css|less)$/,
use: [MiniCssExtractPlugin.loader, "css-loader", "less-loader"],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: [["@babel/plugin-transform-runtime"]],
},
},
},
{
test: /\.json5$/,
type: "json",
parser: {
parse: json5.parse,
},
},
],
},
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
};
2》不同环境的个性化配置:
webpack.config.dev.js文件
module.exports = {
output: {
filename: "[name].js",
},
mode: "development",
devtool: "inline-source-map",
devServer: {
static: "./dist",
},
};
webpack.config.prod.js文件
const CssMinimizerWebpackPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = {
output: {
filename: "[name].[contenthash].js",
// publicPath: "http://localhost:8080/",
},
mode: "production",
optimization: {
minimizer: [new CssMinimizerWebpackPlugin(), new TerserPlugin()],
},
performance: {
hints: false,
},
};
webpack.config.js文件
const { merge } = require("webpack-merge");
const commonConfig = require("./config/webpack.config.common");
const devConfig = require("./config/webpack.config.dev");
const prodConfig = require("./config/webpack.config.prod");
module.exports = (env) => {
switch (true) {
case env.development:
return merge(commonConfig, devConfig);
case env.production:
return merge(commonConfig, prodConfig);
default:
return new Error("matching configuration was not found");
}
};
3》package.json文件script脚本修改
"scripts": {
"dev": "webpack server -c ./webpack.config.js --env development --open ",
"build": "webpack -c ./webpack.config.js --env production"
}