自定义 webpack 配置2:缓存配置

tech2025-10-15  3

参考 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 。


代码仓库

my-webpack-config

参考链接

url-loaderfile-loader缓存extract-text-webpack-pluginmini-css-extract-pluginoptimize-css-assets-webpack-pluginwebpack-bundle-analyzer代码分离
最新回复(0)