Webpack中chunkhash使用报错,如何正确配置?
解决Webpack中
[chunkhash]报错的问题 我来帮你捋捋这个报错的原因和解决办法——其实这个问题本质是Webpack的runtime(也就是manifest chunk)不能用[chunkhash],听我慢慢说:
为什么会报错?
Webpack的manifest/runtime chunk是用来记录所有其他chunk的hash值、加载逻辑的核心代码,它的内容本身就依赖于其他chunk的[chunkhash]。如果给它也用[chunkhash],就会陷入循环依赖:runtime的hash需要其他chunk的hash,而其他chunk的hash又可能因为runtime的变化而改变,所以Webpack直接禁止了这种用法,让你换成[hash]。
另外看你的配置,你手动在entry里加了一个空的manifest入口,这也是问题之一——manifest应该由Webpack的插件自动提取,而不是手动创建空entry。
正确的配置步骤
1. 移除手动的manifest entry
先把entry里的manifest: []删掉,不要手动创建这个chunk,交给插件来处理。
2. 分离Runtime/Manifest Chunk并配置正确的Hash
根据你用的Webpack版本,分两种情况配置:
情况一:Webpack 3及以下版本
用CommonsChunkPlugin先提取vendor公共代码,再单独提取runtime/manifest,给manifest指定[hash]的文件名:
const webpack = require('webpack'); const path = require('path'); module.exports = (env) => { const dev = !env.production; return { entry: { app: './src/index.js', vendor: ['react', 'react-dom'] // 把第三方依赖单独提取 }, output: { path: path.resolve(__dirname, 'dist'), filename: dev ? '[name].js' : '[name].[chunkhash:8].js', chunkFilename: dev ? '[name].js' : '[name].[chunkhash:8].js' }, plugins: [ // 第一步:提取node_modules里的第三方依赖到vendor chunk new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: module => module.context && module.context.includes('node_modules') }), // 第二步:提取runtime/manifest,给它用[hash] new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', filename: dev ? 'manifest.js' : 'manifest.[hash:8].js', minChunks: Infinity // 只提取runtime代码,不包含任何业务或依赖模块 }) ] }; };
情况二:Webpack 4及以上版本
Webpack 4用optimization配置代替了CommonsChunkPlugin,我们可以通过runtimeChunk单独分离runtime,然后用文件名函数区分runtime和其他chunk的hash规则:
const path = require('path'); module.exports = (env) => { const dev = !env.production; return { entry: { app: './src/index.js', vendor: ['react', 'react-dom'] }, output: { path: path.resolve(__dirname, 'dist'), // 用函数判断chunk类型,runtime用[hash],其他用[chunkhash] filename: (pathData) => { return pathData.chunk.name === 'runtime' ? dev ? '[name].js' : '[name].[hash:8].js' : dev ? '[name].js' : '[name].[chunkhash:8].js'; }, chunkFilename: dev ? '[name].js' : '[name].[chunkhash:8].js' }, optimization: { runtimeChunk: 'single', // 把runtime单独拆成一个名为"runtime"的chunk splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'all' } } } } }; };
补充说明
[hash]是整个构建的全局hash,只要项目里任何文件变化,这个hash就会变,适合runtime这种和整个构建绑定的chunk;[chunkhash]是单个chunk的内容hash,只有当这个chunk的代码变化时才会变,适合业务代码和第三方依赖chunk,能实现缓存优化;- 开发环境下尽量不要用
chunkhash或hash,直接用[name].js即可,避免HMR热更新出现问题。
内容的提问来源于stack exchange,提问作者CHARLOT alexandre
相关产品推荐
相关产品推荐

