升级到Webpack 5后无法在copy-webpack-plugin中访问manifest值问题
问题原因
webpack 5 与 webpack-assets-manifest@5 调整了插件执行时序,CopyWebpackPlugin 的 transform 执行时机早于 manifest 数据生成阶段,因此此时读取 manifest 只能拿到空对象。
解决方案
推荐直接使用 webpack-assets-manifest 自带的 transform 配置项完成模板注入,该钩子会在 manifest 数据完全生成后触发,可直接拿到完整的资源映射表,替换原有在 CopyWebpackPlugin 中处理视图模板的逻辑即可。
修改后的配置参考:
var glob = require('glob'); var fs = require('fs'); var path = require('path'); var CopyWebpackPlugin = require('copy-webpack-plugin'); var SaveHashes = require('webpack-assets-manifest'); const manifest = new SaveHashes({ entrypoints: true, entrypointsKey: 'entryPoints', // 新增transform钩子,可直接拿到完整的manifest数据 transform(assets, manifestInstance) { // 遍历所有视图模板文件 const viewFiles = glob.sync('./views/**/*'); viewFiles.forEach(filePath => { // 读取模板原始内容 let content = fs.readFileSync(filePath, 'utf8'); // 注入带hash的js路径,可根据你的模板占位符规则调整替换逻辑 content = content.replace('{{main_js}}', assets.entryPoints.main.assets.js[0]); content = content.replace('{{games_js}}', assets.entryPoints.games.assets.js[0]); // 写入到dist目录对应路径 const outputPath = path.join(__dirname, 'dist', path.relative('./views', filePath)); fs.mkdirSync(path.dirname(outputPath), { recursive: true }); fs.writeFileSync(outputPath, content); }); // 必须返回assets,保证manifest文件正常生成 return assets; } }); module.exports = { entry: { main: ['./src/apps/main'], games: ['./src/apps/games'], }, output: { path: path.join(__dirname, 'dist'), publicPath: assetsUrl, filename: 'assets/javascript/[name].[contenthash].js', chunkFilename: 'assets/javascript/[name].[contenthash].js' }, // 其余原有配置无需修改 plugins: [ new CleanWebpackPlugin(), manifest, new CopyWebpackPlugin([ // 仅保留除视图模板外的其他静态资源复制规则即可,views相关规则可以删除 ]) ] };
注意事项
如果需要注入更多 chunk 资源,直接遍历 assets.entryPoints 对应入口的 assets 数组即可,entrypoints 结构和 v3 版本差异很小,打印 assets 即可快速确认字段结构。
内容的提问来源于stack exchange,提问作者Tripurari Shankar
相关产品推荐
相关产品推荐

