Webpack 4代码分割遇regeneratorRuntime未定义问题(原Webpack3配置正常)
regeneratorRuntime is not defined的问题 Hey,这个问题我之前从Webpack 3升级到4的时候也踩过坑!本质是babel-polyfill的加载顺序出了问题,再加上Webpack 4的代码分割逻辑和3.x版本不一样,才导致了这个报错。
问题到底出在哪?
你把babel-polyfill放进vendor入口的思路在Webpack 3里没问题,但Webpack 4默认开启了splitChunks自动代码分割,这可能会打乱依赖的加载顺序。regeneratorRuntime是babel-polyfill提供的,用来支持async/await这类ES7特性,一旦你的业务代码先于babel-polyfill执行,就会抛出这个未定义的错误。而且Webpack 4已经不推荐手动配置vendor入口来拆分公共代码了,官方更建议用optimization.splitChunks来自动处理。
给你两个可行的解决方案:
方案1:改用官方推荐的代码分割方式(最稳妥)
别再手动维护vendor入口了,直接在你的业务代码最顶部引入babel-polyfill,然后让Webpack自动拆分公共依赖:
- 先修改
src/index.js,把babel-polyfill放在第一行:
// src/index.js 最顶部 import 'babel-polyfill'; // 你的其他业务代码 import moment from 'moment'; // ... 剩下的代码
- 调整Webpack配置,移除
vendor入口,配置splitChunks:
module.exports = { entry: { app: './src/index.js' // 只保留app入口 }, output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') }, optimization: { splitChunks: { chunks: 'all', cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, // 匹配node_modules里的依赖 name: 'vendor', chunks: 'all' } } }, runtimeChunk: 'single' // 单独打包运行时代码,避免缓存问题 }, // 你的babel、loader等其他配置... };
这样Webpack会自动把babel-polyfill、moment这些第三方依赖打包进vendor chunk,并且保证vendor和runtime的加载顺序在app之前,从根源上解决regeneratorRuntime未定义的问题。
方案2:如果一定要保留手动vendor入口
那你必须确保vendor的打包文件在app文件之前被引入到HTML里,同时处理好运行时代码的拆分:
- 保持你的
entry配置不变,但添加runtimeChunk配置:
optimization: { runtimeChunk: 'single' }
- 在HTML模板里按这个顺序引入脚本:
<script src="runtime.[chunkhash].js"></script> <script src="vendor.[chunkhash].js"></script> <script src="app.[chunkhash].js"></script>
这样能保证babel-polyfill先被加载,定义好regeneratorRuntime,再执行你的业务代码。
额外检查:Babel配置要跟上
如果你的Babel版本是7.x以上,建议把.babelrc改成这样,确保polyfill被正确注入:
{ "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 // 如果你用的是corejs@3,需要提前安装它 }] ] }
如果是旧版Babel(比如6.x),记得把useBuiltIns设为entry,配合顶部的import 'babel-polyfill'一起使用。
按照上面的方法调整后,应该就能解决这个错误啦!
内容的提问来源于stack exchange,提问作者DEY

