运行webpack --watch修改非模板文件时图片视频等静态资源丢失如何解决
问题根因
你的图片、视频资源仅被HTML模板引用,watch模式下修改SCSS/JS等非模板文件时,HTML模板不会被重新解析,本轮编译的产出清单不会包含这些未被触发引用的静态资源,加上你开启了output.clean: true,webpack清空dist目录后只会生成本轮清单内的JS、CSS文件,就导致原有图片视频丢失。只有修改HTML模板时才会触发模板解析,资源被加入编译清单,才会重新生成到dist目录。
解决方案
方案1:替换file-loader为webpack5内置Asset Modules(推荐)
webpack5已原生支持静态资源处理,无需额外安装file-loader,对依赖跟踪的兼容性更好:
- 删除原有配置中图片、视频对应的file-loader规则,新增资源模块配置:
module: { rules: [ // 保留原有html、SCSS/JS等规则,替换原file-loader规则为以下内容 { test: /\.(jp(e)?g|png|gif)$/, type: 'asset/resource', generator: { filename: 'assets/img/[name].[contenthash:4][ext]' } }, { test: /\.(mp4|mov)$/, type: 'asset/resource', generator: { filename: 'assets/video/[name].[contenthash:4][ext]' } } ] }
- 修改html-loader配置,开启esModule和资源模块的默认配置对齐:
{ loader: 'html-loader', options: { sources: true, minimize: false, esModule: true // 将原有false改为true } }
调整后webpack会正确跟踪所有HTML引用的静态资源,watch模式下即使不修改HTML模板,资源也会被保留在编译清单中,不会被清理,同时自动带hash值满足缓存要求。
方案2:兼容旧版本webpack的兜底方案
如果因为项目兼容原因必须使用file-loader,可以通过copy-webpack-plugin直接复制静态资源目录,同时保留hash命名能力:
- 安装依赖:
npm install copy-webpack-plugin --save-dev - 在plugins配置中添加插件:
const CopyPlugin = require("copy-webpack-plugin"); plugins: [ // 保留原有HtmlWebpackPlugin、MiniCssExtractPlugin等插件 new CopyPlugin({ patterns: [ { from: path.resolve(__dirname, config.src, 'assets/img'), to: path.resolve(__dirname, config.dist, 'assets/img/[name].[contenthash:4][ext]'), noErrorOnMissing: true }, { from: path.resolve(__dirname, config.src, 'assets/video'), to: path.resolve(__dirname, config.dist, 'assets/video/[name].[contenthash:4][ext]'), noErrorOnMissing: true } ], }), ]
该方案无需修改现有加载器配置,静态资源会被独立复制到dist目录,不会受模板编译逻辑影响出现丢失问题。
内容的提问来源于stack exchange,提问作者coreuter
相关产品推荐
相关产品推荐

