一、区分环境
目前所有的webpack配置信息都是放到一个配置文件中的:webpack.config.js
当配置越来越多时,这个文件会变得越来越不容易维护;
并且某些配置是在开发环境需要使用的,某些配置是在生成环境需要使用的
最好对配置进行划分,方便维护和管理

- 方案一:编写两个不同的配置文件,开发和生成时,分别加载不同的配置文件即可
1 2
| "build": "webpack --config ./config/webpack.prod.js", "serve": "webpack serve --config ./config/webpack.dev.js",
|
- 方式二:使用相同的一个入口配置文件,通过设置参数来区分它们
1 2
| "build2": "webpack --config ./config/webpack.common.js --env production", "serve2": "webpack serve --config ./config/webpack.common.js --env development"
|
1 2 3 4 5 6 7 8 9
| module.exports = function(env) { const isProduction = env.production; process.env.NODE_ENV = isProduction ? "production": "development";
const config = isProduction ? prodConfig : devConfig; const mergeConfig = merge(commonConfig, config);
return mergeConfig; };
|
入口文件解析
之前编写入口文件的规则是这样的:./src/index.js,但是如果配置文件所在的位置变成了 config 目录,我们是否应该变成 ../src/index.js呢?
这样编写,会发现是报错的,依然要写成 ./src/index.js;
因为入口文件其实是和另一个属性时有关的 context;
context的作用是用于解析入口(entry point)和加载器(loader):
官方说法:默认是当前路径(经过测试,默认应该是webpack的启动目录,也就是根目录)
另外推荐在配置中传入一个值;

抽离文件
路径文件path.js
1 2 3 4 5 6 7 8 9
| const path = require('path');
const appDir = process.cwd();
console.log('-----------------------------------', process.cwd()); const resolveApp = (relativePath) => path.resolve(appDir, relativePath); module.exports = resolveApp;
|
公共配置文件 webpack.common.js
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| const resolveApp = require('./paths'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const VueLoaderPlugin = require('vue-loader/lib/plugin'); const { merge } = require('webpack-merge');
const prodConfig = require('./webpack.prod'); const devConfig = require('./webpack.dev');
const commonConfig = { entry: './src/index.js', output: { filename: 'bundle.js', path: resolveApp('./build'), }, resolve: { extensions: ['.wasm', '.mjs', '.js', '.json', '.jsx', '.ts', '.vue'], alias: { '@': resolveApp('./src'), pages: resolveApp('./src/pages'), }, }, module: { rules: [ { test: /\.jsx?$/i, use: 'babel-loader', }, { test: /\.vue$/i, use: 'vue-loader', }, { test: /\.css/i, use: ['style-loader', 'css-loader'], }, ], }, plugins: [ new HtmlWebpackPlugin({ template: './index.html', }), new VueLoaderPlugin(), ], };
module.exports = function(env) { const isProduction = env.production; process.env.NODE_ENV = isProduction ? 'production' : 'development'; const config = isProduction ? prodConfig : devConfig; const mergeConfig = merge(commonConfig, config); return mergeConfig; };
|
开发环境webpack.dev.js
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 31 32 33
| const resolveApp = require('./paths'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const isProduction = false;
module.exports = { mode: "development", devServer: { hot: true, hotOnly: true, compress: true, contentBase: resolveApp("./why"), watchContentBase: true, proxy: { "/why": { target: "http://localhost:8888", pathRewrite: { "^/why": "" }, secure: false, changeOrigin: true } }, historyApiFallback: { rewrites: [ {from: /abc/, to: "/index.html"} ] } }, plugins: [ new ReactRefreshWebpackPlugin(), ] }
|
生产环境webpack.prod.js
1 2 3 4 5 6 7 8 9 10
| const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const isProduction = true;
module.exports = { mode: "production", plugins: [ new CleanWebpackPlugin({}), ] }
|
注意babel.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const presets = [ ["@babel/preset-env"], ["@babel/preset-react"], ]; const plugins = []; const isProduction = process.env.NODE_ENV === "production";
if (!isProduction) { plugins.push(["react-refresh/babel"]); } else {
} module.exports = { presets, plugins }
|