webpack5多入口应用报__webpack_require__.r is not a function问题咨询
问题原因解答
1. 为什么会加载独立chunk中的模块C,而非B入口自带的C模块
你开启了splitChunks: 'all'配置,webpack会将多个入口共用的依赖提取为独立公共chunk。但由于你将多个入口的构建产物同时加载在同一个全局作用域下,webpack默认的模块注册机制依赖全局的chunk加载回调队列,先加载的入口会将已解析的模块ID注册到全局作用域,后续加载的入口如果存在相同ID的模块,会直接复用全局已注册的模块,不会再加载自身内置的同ID模块,因此入口B调用模块C时拿到的是入口A提取的公共chunk里的C。
2. 为什么B的入口产物中没有定义r方法
webpack会按需打包运行时方法,只有当入口自身包含的模块需要用到ES模块标记(也就是__webpack_require__.r的功能)时,才会将r方法打入当前入口的运行时代码中。由于入口B内置的模块C没有ES模块标记的相关逻辑,webpack在构建优化阶段会将未用到的r方法从B的运行时中剔除,当公共chunk里的模块C运行时调用r方法时,实际访问的是入口B的运行时,自然会抛出方法不存在的错误。
解决方案
不建议单独强制给入口补r方法,这种方案属于临时修复,后续还可能出现其他运行时方法缺失的问题,推荐使用以下两种更稳妥的方案:
- 抽取统一的公共运行时:在webpack配置中添加
optimization.runtimeChunk: 'single',将所有入口共用的webpack运行时代码单独打包为一个独立文件,所有入口加载前先加载该运行时文件,确保运行时方法全局统一,不会出现缺失问题。如果你的多个入口是来自不同的webpack构建任务,还可以给每个构建的output.uniqueName配置不同的命名空间,避免运行时全局变量冲突。 - 调整公共chunk提取规则:修改
splitChunks配置的minChunks、minSize等参数,确保所有被多个入口引用的公共模块都会被提取到独立公共chunk中,避免出现部分入口内置公共模块、部分入口复用公共chunk的不一致情况。
内容的提问来源于stack exchange,提问作者Joep Ronde
相关产品推荐
相关产品推荐

