区分开发环境和线上环境
开发阶段
在开发阶段我们为了提升运行效率以及调试效率, 一般会通过 dev-server
来打包, 在开发阶段我们为了提升打包效率, 不会对打包的内容进行压缩
上线阶段
在上线阶段我们需要拿到真实的打包文件, 所以不会通过 dev-server
来打包,在上线阶段我们为了提升访问的效率, 所以在打包时需要对打包的内容进行压缩
但是当前我们将 "开发环境和线上环境"
的配置都写到了一个文件中, 这样非常不利于我们去维护配置文件, 所以我们需要针对不同的环境将不同的配置写到不同的文件中
区分开发环境和线上环境配置文件优化
不同环境配置文件之间存在大量重复配置,这时可以利用 webpack-merge
模块来实现冗余代码的抽离和合并进一步优化配置文件:
将冗余代码抽取到 webpack.config.common.js
中创建 webpack.config.common.js 内容如下:
const path = require('path');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
/*
entry: 指定需要打包的文件
* */
entry: './src/js/index.js',
/*
output: 指定打包之后的文件输出的路径和输出的文件名称
* */
output: {
/*
filename: 指定打包之后的JS文件的名称
* */
filename: 'js/bundle.js',
/*
path: 指定打包之后的文件存储到什么地方
* */
path: path.resolve(__dirname, 'bundle')
},
/*
module: 告诉webpack如何处理webpack不能够识别的文件
* */
module: {
rules: [
// 检查编码规范的规则
{
// enforce: "pre"作用: 让当前的loader再其它loader之前执行
enforce: "pre",
test: /\.js$/,
exclude: /node_modules/,
include: path.resolve(__dirname, "src"),
loader: 'eslint-loader',
options: {
// eslint options (if necessary)
fix: true
},
},
// 打包JS规则
{
test: /\.js$/,
exclude: /node_modules/, // 告诉webpack不处理哪一个文件夹
loader: 'babel-loader',
options: {
presets: [['@babel/preset-env', {
targets: {
// "chrome": "58",
}
// useBuiltIns: "usage"
}]],
plugins: [
['@babel/plugin-proposal-class-properties', {loose: true}],
[
'@babel/plugin-transform-runtime',
{
absoluteRuntime: false,
corejs: 2,
helpers: true,
regenerator: true,
useESModules: false
}
]
]
}
},
// 打包字体图标规则
{
test: /\.(eot|json|svg|ttf|woff|woff2)$/,
use: [
{
loader: 'file-loader',
options: {
// 指定打包后文件名称
name: '[name].[ext]',
// 指定打包后文件存放目录
outputPath: 'font/'
}
}
]
},
// 打包图片规则
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// 指定图片限制的大小
limit: 1024,
// 指定打包后文件名称
name: '[name].[ext]',
// 指定打包后文件存放目录
outputPath: 'images/',
publicPath: 'http://127.0.0.1:9090/images'
}
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
}
]
},
{
test: /\.(htm|html)$/i,
loader: 'html-withimg-loader'
},
// 打包CSS规则
{
test: /\.css$/,
use: [
{
// loader: "style-loader"
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true
}
},
{
loader: 'css-loader',
options: {
// modules: true // 开启CSS模块化
}
},
{
loader: 'postcss-loader'
}
]
},
// 打包LESS规则
{
test: /\.less$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'less-loader'
}, {
loader: 'postcss-loader'
}]
},
// 打包SCSS规则
{
test: /\.scss$/,
use: [{
loader: 'style-loader'
}, {
loader: 'css-loader'
}, {
loader: 'sass-loader'
}, {
loader: 'postcss-loader'
}]
}
]
},
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new CleanWebpackPlugin(),
new CopyWebpackPlugin([{
from: './doc',
to: 'doc'
}]),
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
]
};
创建 webpack.config.dev.js
利用 merge
合并 webpack.config.common.js
即可内容如下:
const Webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.config.common.js");
const DevConfig = {
/*
devServer: 自动检测文件变化配置
* */
devServer: {
contentBase: './bundle',
open: true,
port: 9090,
proxy: [{
context: ['/user', '/login'],
target: 'http://127.0.0.1:3000',
changeOrigin: true, // 域名跨域
secure: false, // https跨域
pathRewrite: {'': '/api'} // 路径重写, 将路径中的api替换为空
}],
hot: true, // 开启热更新, 只要开启了热更新就不会自动刷新网页了
hotOnly: true // 哪怕不支持热更新也不要刷新网页
},
/*
配置sourcemap
development: cheap-module-eval-source-map
production: cheap-module-source-map
* */
devtool: 'cheap-module-eval-source-map',
/*
mode: 指定打包的模式, 模式有两种
一种是开发模式(development): 不会对打包的JS代码进行压缩
还有一种就是上线(生产)模式(production): 会对打包的JS代码进行压缩
* */
mode: 'development', // "production" | "development"
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new HtmlWebpackPlugin({
// 指定打包的模板, 如果不指定会自动生成一个空的
template: './src/index.html',
}),
new Webpack.HotModuleReplacementPlugin()
]
};
module.exports = Merge(CommonConfig, DevConfig);
创建 webpack.config.prod.js
利用 merge
合并 webpack.config.common.js
即可内容如下:
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserJSPlugin = require('terser-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const Merge = require("webpack-merge");
const CommonConfig = require("./webpack.config.common.js");
const ProdConfig = {
/*
optimization: 配置webpack的优化项
* */
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
},
/*
配置sourcemap
development: cheap-module-eval-source-map
production: cheap-module-source-map
* */
devtool: 'cheap-module-source-map',
/*
mode: 指定打包的模式, 模式有两种
一种是开发模式(development): 不会对打包的JS代码进行压缩
还有一种就是上线(生产)模式(production): 会对打包的JS代码进行压缩
* */
mode: 'production', // "production" | "development"
/*
plugins: 告诉webpack需要新增一些什么样的功能
* */
plugins: [
new HtmlWebpackPlugin({
// 指定打包的模板, 如果不指定会自动生成一个空的
template: './src/index.html',
minify: {
// 告诉htmlplugin打包之后的html文件需要压缩
collapseWhitespace: true,
}
}),
]
};
module.exports = Merge(CommonConfig, ProdConfig);
然后更改一下 package.json 添加一个开发环境的启动脚本去利用 webpack.config.dev.js
进行启动打包,在添加一个生产环境的启动脚本按照 webpack.config.prod.js
所配置的规则去进行打包:
"scripts": {
"start": "npx webpack-dev-server --config webpack.config.dev.js",
"dev": "npx webpack --config webpack.config.dev.js",
"prod": "npx webpack --config webpack.config.prod.js"
},
按照 开发环境配置文件
打包效果如下:
按照 生产环境配置文件
打包效果如下: