如何配置Webpack保留最近3次构建文件解决懒加载报错
Webpack保留最近3个构建版本、解决懒加载chunk404的配置方法
Webpack 5 内置的output.clean: true默认会全量清空输出目录,没有多版本保留能力,直接用就会出现懒加载chunk丢失、旧页面必须刷新才能访问的问题,按下面的配置就能实现保留最近3个版本的效果:
- 首先调整产物输出规则,按构建版本做目录隔离
别把所有版本的JS文件全堆在dist根目录,不然新构建的文件会和旧文件混在一起,清理的时候很容易误删正在被旧页面引用的资源。每次构建生成独立的版本子目录,所有当前版本的初始chunk、懒加载chunk都放到对应子目录下,配置参考:const path = require('path'); // 版本标识直接用构建时间戳就行,要更精准也可以取git commit hash const BUILD_VERSION = Date.now().toString(); module.exports = { output: { path: path.resolve(__dirname, 'dist'), filename: `${BUILD_VERSION}/[name].[contenthash].js`, chunkFilename: `${BUILD_VERSION}/[name].[contenthash].js`, // 先关内置的全量清理,后面用自定义逻辑处理 clean: false, publicPath: '/' // 必须配正确,不然懒加载chunk的请求路径会出错 } } - 加个轻量的自定义插件,构建完成后自动清理超过3个版本的旧目录
不用额外装第三方插件,直接用Webpack的编译钩子写少量代码就行,逻辑很简单:构建完扫一遍dist目录,把所有版本目录按构建时间倒序排,只留最新的3个,剩下的全删掉。代码可直接复用:const fs = require('fs'); const path = require('path'); class CleanOldBuildPlugin { apply(compiler) { compiler.hooks.afterEmit.tap('CleanOldBuildPlugin', () => { const distPath = path.resolve(__dirname, 'dist'); // 过滤出生成的纯数字命名的版本目录,避免误删根目录下放的favicon、固定静态资源等文件 const versionDirs = fs.readdirSync(distPath).filter(file => { const fullPath = path.join(distPath, file); return fs.statSync(fullPath).isDirectory() && /^\d+$/.test(file); }).sort((a, b) => Number(b) - Number(a)); // 最新的版本排在最前面 // 从第4个版本开始删除,正好保留最近3个 versionDirs.slice(3).forEach(oldDir => { fs.rmSync(path.join(distPath, oldDir), { recursive: true, force: true }); }); }); } } // 把这个插件加到webpack配置的plugins数组里即可 module.exports.plugins = [new CleanOldBuildPlugin()] - 如果用HtmlWebpackPlugin自动生成入口HTML,不需要额外改路径,插件会自动识别output里的路径规则,把最新版本的入口JS引用插到HTML里。新打开页面的用户直接加载最新版本资源,已经停留在旧版本页面的用户,请求懒加载chunk的时候会走对应版本的目录路径,只要该版本还在保留期内就不会报404,用户不用手动刷新,也不会丢失未保存的表单数据。
要是你把构建产物上传到CDN使用,逻辑完全一致,把本地清理逻辑换成CDN侧的版本保留规则,保留最近3个版本的目录即可,Webpack侧的命名配置不需要修改。
内容的提问来源于stack exchange,提问作者Ansagan Islamgali
相关产品推荐
相关产品推荐

