Webpack4与5的核心不同
- merge函数的引入方式
// const merge = require("webpack-merge");
const { merge } = require("webpack-merge");
- CSS的压缩插件变化:
由
optimize-css-assets-webpack-plugin变更为css-minimizer-webpack-plugin
// const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
...
optimization: {
...
minimizer: [
new TerserPlugin(),
// new OptimiazeCssAssetPlugin(),
new CssMinimizerPlugin(),
],
...
}
- optimization中的压缩配置变化
optimization: {
/* Webpack4 => Webpack5 */
// minimizer: [
// new TerserPlugin(),
// new OptimizeCssAssetsPlugin({})
// ],
usedExports: true, //只导出被使用的模块
minimize: true, // 启动压缩
concatenateModules: true,
minimizer: [
new TerserPlugin(),
// new OptimiazeCssAssetPlugin(),
new CssMinimizerPlugin(),
],
},
- 图片文件的加载方式由file-loader/url-loader变更为assets类型定义
关于asset详见:官方文档描述
// {
// test: /\.(png|jpg|jpeg|gif)$/,
// use: {
// loader: "url-loader",
// options: {
// // 小于 5kb 的图片用 base64 格式产出
// // 否则,依然延用 file-loader 的形式,产出 url 格式
// limit: 5 * 1024,
// // 打包到 img 目录下
// outputPath: "img/",
// // 不一定以ESM模块形式去引入
// // 不要看到源代码中未以ESM模块形式去引入a.png 就给哥tree-shaking掉(html中可能以src形式引用)
// esModule: false,
// },
// },
// },
{
// 图标的转化
test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
type: "asset/resource",
},
{
// 图片的转化
test: /\.(jpe?g|png|gif|bmp)$/i,
// type: "asset/resource",
// type: "asset/inline",
// 自动切换resource与inline
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 8192, // 8kb
},
},
},
以下是一个比较典型的Webpack5工程配置案例
/* 引入webpack及配置合并函数 */
const webpack = require("webpack");
/* Webpack4 => Webpack5 */
// const merge = require("webpack-merge");
const { merge } = require("webpack-merge");
/* 引入本地输出路径 */
const path = require("path");
const { srcPath, distPath, wwwPath } = require("./path");
/* 引入通用配置对象(等待合并) */
const commonConf = require("./webpack.common.js");
/* 引入各种功能插件 */
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
/* Webpack4 => Webpack5 */
// const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
/* 输出模式 */
// mode: "development",
mode: "production",
/* 入口文件 每个入口文件对应着一棵依赖树 */
entry: {
index: path.join(srcPath, "js", "index.js"),
other: path.join(srcPath, "js", "other.js"),
},
/* bundle输出位置 */
/* dev */
// output: {
// filename: "[name].[hash].js", // 打包代码时,加上 hash 戳
// path: distPath,
// },
/* prod */
output: {
filename: "[name].[contenthash:8].js", // 打包代码时,加上 hash 戳
path: wwwPath,
// 如果有CDN
// publicPath: 'http://cdn.abc.com'
// 异步chunk输出位置
chunkFilename: "async/[id].js",
},
/* 使用不同【loader+具体配置】去编译加载不同【源码模块】 */
module: {
rules: [
/* common */
{
// 找到所有的js文件
test: /\.js$/, // 使用babel-loader做ES高级语法向ES5的转换
use: ["babel-loader"] /* 以下两个只需要写一个 */,
// 查找范围仅限于src目录
include: srcPath,
exclude: /node_modules/,
},
// 开发环境下CSS的配置
{
test: /\.css$/,
// loader 的执行顺序是:从后往前
/*
postcss.config.js中的配置
module.exports = {
plugins: [require("autoprefixer")],
};
*/
use: ["style-loader", "css-loader", "postcss-loader"],
},
/* Webpack4 => Webpack5 */
/* 关于asset详见:https://webpack.docschina.org/guides/asset-modules/ */
// {
// test: /\.(png|jpg|jpeg|gif)$/,
// use: [
// {
// loader: "file-loader",
// options: {},
// },
// ],
// },
{
// 图片的转化
test: /\.(jpe?g|png|gif|bmp)$/i,
type: "asset/resource",
},
// scss开发环境
{
test: /\.scss$/, // 增加 'less-loader' ,注意顺序
use: [
"style-loader",
"css-loader",
"sass-loader",
"postcss-loader",
],
},
/* prod */
/* Webpack4 => Webpack5 */
/* 关于asset详见:https://webpack.docschina.org/guides/asset-modules/ */
// {
// test: /\.(png|jpg|jpeg|gif)$/,
// use: {
// loader: "url-loader",
// options: {
// // 小于 5kb 的图片用 base64 格式产出
// // 否则,依然延用 file-loader 的形式,产出 url 格式
// limit: 5 * 1024,
// // 打包到 img 目录下
// outputPath: "img/",
// // 不一定以ESM模块形式去引入
// // 不要看到源代码中未以ESM模块形式去引入a.png 就给哥tree-shaking掉(html中可能以src形式引用)
// esModule: false,
// },
// },
// },
{
// 图标的转化
test: /\.(woff|woff2|eot|ttf|otf|svg)$/i,
type: "asset/resource",
},
{
// 图片的转化
test: /\.(jpe?g|png|gif|bmp)$/i,
// type: "asset/resource",
// type: "asset/inline",
// 自动切换resource与inline
type: "asset",
parser: {
dataUrlCondition: {
maxSize: 8192, // 8kb
},
},
},
// 生产环境下CSS配置
// 抽离 css
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
],
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader",
"sass-loader",
"postcss-loader",
],
},
],
},
plugins: [
/* common */
new HtmlWebpackPlugin({
template: `html-withimg-loader!${path.join(srcPath, "index.html")}`,
filename: "index.html",
minify: {
collapseWhitespace: true,
keepClosingSlash: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
},
chunks: ["index", "common"],
}),
new HtmlWebpackPlugin({
template: `html-withimg-loader!${path.join(
srcPath,
"views",
"other.html"
)}`,
filename: "other.html",
minify: {
collapseWhitespace: true,
keepClosingSlash: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true,
},
chunks: ["other", "common", "vendor"],
}),
/* dev */
new webpack.DefinePlugin({
// 相当于window.ENV = 'production'
ENV: JSON.stringify("development"),
}),
// 会默认清空 output.path 文件夹
new CleanWebpackPlugin(),
/* prod */
// 抽离 css 文件
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash:8].css",
}),
new webpack.DefinePlugin({
ENV: JSON.stringify("production"),
}),
new CleanWebpackPlugin(),
],
/* dev */
devServer: {
hot: true, // 热更新
port: 8000, // 测试服务器端口
open: true, // 自动打开浏览器
compress: true, // 启动 gzip 压缩
proxy: {
"/api": {
target: "http://localhost:9000/api",
changeOrigin: true,
ws: true,
pathRewrite: {
"^/api": "",
},
},
},
},
/* prod */
optimization: {
/* Webpack4 => Webpack5 */
// minimizer: [
// new TerserPlugin(),
// new OptimizeCssAssetsPlugin({})
// ],
usedExports: true, //只导出被使用的模块
minimize: true, // 启动压缩
concatenateModules: true,
minimizer: [
new TerserPlugin(),
// new OptimiazeCssAssetPlugin(),
new CssMinimizerPlugin(),
],
splitChunks: {
// 同步异步都使用分包
chunks: "all",
cacheGroups: {
// 第三方模块
vendor: {
name: "vendor", // chunk 名称
priority: 1, // 权限更高的优先抽离,重要!!!
test: /[\\/]node_modules[\\/]/,
minSize: 0, // 大小限制
minChunks: 1, // 最少复用过几次
},
// 公共的模块
common: {
name: "common", // chunk 名称
test:/[\\/]src[\\/]utils[\\/]/
priority: 2, // 优先级
minSize: 0, // 公共模块的大小限制
minChunks: 1, // 公共模块最少复用过几次
},
},
},
},
};
以下是一个能跑起来的Webpack5工程配置
git clone https://gitee.com/steveouyang/learn_webpack.git
cd learn_js_pro
git checkout feat2-wp5
npm i
npm run mock
npm run dev
npm run build
配套的Nginx配置
server {
listen 8002;
server_name localhost;
root "D:/phpStudy/WWW/jdzb_client_js";
location / {
index index.html;
autoindex on;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
location /api {
proxy_pass http://10.3.134.65:9000/api;
}
}