项目开发时一般需要使用两套配置文件,用于开发阶段打包(不压缩代码,不优化代码,增加效率)和上线阶段打包(压缩代码,优化代码,打包后直接上线使用)
抽取三个配置文件:
- webpack.base.js
- webpack.prod.js
- webpack.dev.js
步骤如下:
- 将开发环境和生产环境公用的配置放入 base 中,不同的配置各自放入 prod 或 dev 文件中。
- 然后在 dev 和 prod 中使用
webpack-merge
把自己的配置与 base 的配置进行合并后导出 - 将 package.json 中的脚本参数进行修改,通过
--config
手动指定特定的配置文件
安装 webpack-merge
npm i webpack-merge -D
分离
project dir
|_config
|_webpack.base.js
|_webpack.dev.js
|_webpack.prod.js
|_src
|_package.json
webpack.dev.js
// webpack.dev.js
const merge = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const devConfig = {
mode: 'development',
// 配置 webpack-dev-server
devServer: {
open: true,
compress: true,
hot: true,
port: 3000,
contentBase: './src'
},
// 配置 source map
devtool: "cheap-module-eval-source-map"
}
module.exports = merge(baseConfig, devConfig)
webpack.prod.js
const merge = require('webpack-merge')
const baseConfig = require('./webpack.config.base')
const prodConfig = {
mode: 'production'
}
module.exports = merge(baseConfig, prodConfig)
:::danger 在 webpack 配置文件中使用绝对路径的配置,需要修改目录,比如:
- path.join(__dirname, ‘dist’)
- 修改为 path.join(__dirname, ‘..’, ‘dist’) :::
package.json
"scripts": {
"build": "webpack --config ./config/webpack.config.prod.js",
"dev": "webpack-dev-server --config ./config/webpack.config.dev.js",
"dev2": "webpack-dev-server",
"test": "echo \"Error: no test specified\" && exit 1"
},
webpack.base.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const webpack = require('webpack')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, '..', '/dist/'), // <= 修改目录
filename: "bundle.js"
},
plugins: [
// 配置 html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html', // 在内存中生成的文件名
template: './src/index.html' // 模板,以磁盘上的这个文件为模板,不用引入 bundle.js
}),
// 配置 clean-webpack-plugin
new CleanWebpackPlugin(),
new CopyWebpackPlugin([
{
from: path.join(__dirname, '..', 'assets'),
to: 'assets'
}
]),
new webpack.BannerPlugin('MangoLee!')
],
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'] // loader 从右向左 执行
},
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader']
},
{
test: /\.s(c|a)ss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
},
{
test: /\.(jpg|jpeg|png|gif|bmp)$/,
use: {
loader: 'url-loader',
options: {
limit: 5*1024, // 5kb以下的用base64编码,5kb以上的用原图片
outputPath: 'images', // 输出到images文件夹中
name: '[name]-[hash:4].[ext]' // 重命名
}
}
},
{
test: /\.(woff|woff2|eot|svg|ttf)$/,
use: 'url-loader'
},
{// 配置 babel
test: '/\.js$/',
use: {
loader: "babel-loader",
options: {
presets: ['@babel/env'], // 语法预设,可以设置多个语法预设
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-transform-runtime'
]
}
}
},
{
test: /\.(htm|html)$/i,
loader: 'html-withimg-loader'
},
{
test: require.resolve('jquery'),
use: {
loader: "expose-loader",
options: '$'
}
}
]
},
}