参考 webpack教程、create-react-app(eject后)配置,自定义一个适合的、可维护的webpack配置
-
使用 webpack 来打包我们的模块化后的应用程序,会生成一个可部署的
/dist
目录,打包后的内容放置在此目录中。只要/dist
目录中的内容部署到服务器上,客户端(通常是浏览器)就能够访问网站此服务器的网站及其资源。 -
浏览器使用一种名为缓存的技术。可以通过命中缓存,以降低网络流量,使网站加载速度更快。在部署新版本时不更改资源的文件名,浏览器可能会认为它没有被更新,就会使用它的缓存版本。
-
通过必要的配置,以确保 webpack 编译生成的文件能够被客户端缓存,而在文件内容变化后,能够请求到新的文件。
1. 资源缓存
1.1 修改 webpack.base.js 中 file-loader 配置
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: "file-loader",
options: {
name: "static/media/[name].[hash:8].[ext]",
},
},
],
}
1.2 修改 webpack.base.js 中 url-loader 配置
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
use: [
{
loader: "url-loader",
options: {
limit: 51200, //50k
name: "static/media/[name].[hash:8].[ext]",
},
},
],
}
1.3 构建成功后可以看到 图片和字体文件出现在dist/static/media
文件夹中
big.efb37eb0.png
font.d55bf3f0.ttf
2. JavaScript 缓存
2.1 修改 webpack.base.js 中 output 配置
output: {
filename: "static/js/[name].[contenthash:8].js",
},
1.2 构建成功后可以看到 JavaScript 文件出现在dist/static/js
文件夹中
main.5532aaad.js
3. CSS 缓存
3.1 抽取 CSS
3.1.1 安装插件
yarn add mini-css-extract-plugin -D
3.1.2 修改 webpack.base.js 文件
const pathsUtil = require("./pathsUtil");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
//指定入口文件
entry: pathsUtil.appIndexJs,
output: {
filename: "static/js/[name].[contenthash:8].js",
},
module: {
rules: [
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
presets: [["@babel/preset-env"], "@babel/preset-react"],
},
},
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: { publicPath: "../../" },
},
"css-loader",
],
},
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
use: [
{
loader: "url-loader",
options: {
limit: 51200, //50k
name: "static/media/[name].[hash:8].[ext]",
},
},
],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: "file-loader",
options: {
name: "static/media/[name].[hash:8].[ext]",
},
},
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: pathsUtil.appHtml,
inject: true,
}),
new MiniCssExtractPlugin({
filename: "static/css/[name].[contenthash:8].css",
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
}),
],
};
3.1.3 构建成功后可以看到 CSS 文件出现在dist/static/css
文件夹中
main.52aa0dde.css
.color {
color: rebeccapurple;
}
@font-face {
font-family: myFirstFont;
src: url(static/media/font.d55bf3f0.ttf);
}
.font {
font-family: myFirstFont;
}
3.2 压缩 CSS
3.2.1 安装插件
yarn add optimize-css-assets-webpack-plugin -D
3.2.2 修改 webpack.prod.js 文件
开发环境不需要压缩
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = merge(baseConfig, {
mode: "production",
plugins: [new OptimizeCssAssetsPlugin()],
});
3.2.3 构建成功后可以看到 CSS 文件出现在dist/static/css
文件夹中
main.52aa0dde.css
.color{color:#639}@font-face{font-family:myFirstFont;src:url(static/media/font.d55bf3f0.ttf)}.font{font-family:myFirstFont}
4. bundle 分析
在进行 提取引导模板 和 防止重复 之前先安装 bundle 分析 工具。
4.1 安装依赖
yarn add -D webpack-bundle-analyzer
4.2 编辑 webpack.prode.js 文件
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = smp.wrap(
merge(baseConfig, {
mode: "production",
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(),
new OptimizeCssAssetsPlugin(),
new BundleAnalyzerPlugin({ analyzerMode: "static" }),
// 暂时屏蔽,太耗时
//Make sure that the plugin is after any plugins that add images
// new ImageminPlugin({
// pngquant: {
// quality: "95-100",
// },
// }),
],
})
);
4.3 重新构建
在 dist 目录下生成 report.html 文件
index.html 0.35K
static/css/main.ad7a61d4.css 0.23K
static/js/main.8ba15055.js 191.13K
static/js/main.8ba15055.js.map 373.05K
static/media/big.efb37eb0.png 4303.18K
static/media/font.d55bf3f0.ttf 77.86K
5. 提取引导模板
5.1 编辑 webpack.prode.js 文件
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.base.js");
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ImageminPlugin = require("imagemin-webpack-plugin").default;
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer")
.BundleAnalyzerPlugin;
module.exports = smp.wrap(
merge(baseConfig, {
mode: "production",
devtool: "source-map",
plugins: [
new CleanWebpackPlugin(),
new OptimizeCssAssetsPlugin(),
new BundleAnalyzerPlugin({ analyzerMode: "static" }),
// 暂时屏蔽,太耗时
//Make sure that the plugin is after any plugins that add images
// new ImageminPlugin({
// pngquant: {
// quality: "95-100",
// },
// }),
],
optimization: {
runtimeChunk: "single",
},
})
);
5.2 重新构建
在 dist 目录下生成 report.html 文件
static/css/main.ad7a61d4.chunk.css 0.23K
static/js/main.a4b90f3e.js 190.30K
static/js/main.a4b90f3e.js.map 367.78K
static/js/runtime.1ee16c22.js 1.50K
static/js/runtime.1ee16c22.js.map 8.07K
static/media/big.efb37eb0.png 4303.18K
static/media/font.d55bf3f0.ttf 77.86K
6. 防止重复导入
6.1 添加新的入口文件
6.1.1 编辑 webpack.base.js 文件
entry: {
index: pathsUtil.appIndexJs,
index2: pathsUtil.appIndex2Js,//复制粘贴 index.js 内容
},
6.1.2 重新构建
在 dist 目录下生成 report.html 文件
index.html 0.53K
static/css/index.ad7a61d4.chunk.css 0.23K
static/css/index2.ad7a61d4.chunk.css 0.23K
static/js/index.f769b13e.js 190.39K
static/js/index.f769b13e.js.map 367.79K
static/js/index2.354d10c2.js 190.39K
static/js/index2.354d10c2.js.map 367.79K
static/js/runtime.f00dbe9b.js 1.50K
static/js/runtime.f00dbe9b.js.map 8.07K
static/media/big.efb37eb0.png 4303.18K
static/media/font.d55bf3f0.ttf 77.86K
可以看出,index 和 index2 均为 190.39K, node_modules 中的文件被重复打包,需要抽取公共包
6.2 编辑 webpack.prod.js 文件
optimization: {
runtimeChunk: "single",
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendors",
chunks: "all",
},
},
},
},
6.3 重新构建
在 dist 目录下生成 report.html 文件
static/css/index.ad7a61d4.chunk.css 0.23K
static/css/index2.ad7a61d4.chunk.css 0.23K
static/js/index.58fc8036.js 63.90K
static/js/index.58fc8036.js.map 62.87K
static/js/index2.829aa779.js 63.91K
static/js/index2.829aa779.js.map 62.87K
static/js/runtime.f00dbe9b.js 1.50K
static/js/runtime.f00dbe9b.js.map 8.07K
static/js/vendors.eea1f403.js 126.60K
static/js/vendors.eea1f403.js.map 305.04K
static/media/big.efb37eb0.png 4303.18K
static/media/font.d55bf3f0.ttf 77.86K
可以看出 index 和 index2 均为 63.90K ,node_modules 中的文件被抽取公共包 vendors 。
代码仓库
参考链接