Webpack 5中为何require.ensure的两种不同写法会导致代码分割失败?
Webpack 5中require.ensure链式调用default导致代码分割失效的原因
这是个很值得注意的细节问题,我来给你拆解背后的原因:
测试场景(Webpack 5 默认配置)
代码分割成功的写法
// chunk1.js export const a = 'xxx' // index.js require.ensure( [], (require) => { const mod = require('./chunk1') mod.default }, 'chunk1' )
输出文件:main.js、chunk1.js
代码分割失败的写法
// chunk1.js export const a = 'xxx' // index.js require.ensure( [], (require) => { require('./chunk1').default }, 'chunk1' )
输出文件:main.js(包含chunk1.js的全部内容)
失效原因解析
核心问题出在Webpack的静态语法分析逻辑上:
Webpack实现代码分割的前提是,它能通过静态扫描识别出哪些模块属于异步加载的依赖。在require.ensure的回调函数中,Webpack需要明确看到独立的require(模块路径)调用,才能标记这个模块为需要拆分的异步chunk。
- 在成功的写法里,你把
require('./chunk1')的结果赋值给了变量mod,再单独访问mod.default。这种写法让Webpack能清晰识别到./chunk1是一个独立的异步依赖,因此会将其打包为单独的chunk1.js。 - 在失败的写法里,你直接使用了链式调用
require('./chunk1').default。此时Webpack的静态分析器会把整个表达式视为一个不可拆分的整体,无法单独识别出./chunk1是需要异步加载的模块。它会默认将这个模块的内容合并进主chunkmain.js,最终导致代码分割失效。
简单来说:Webpack的静态分析需要“明确的模块引用”,链式调用的写法模糊了模块的边界,干扰了它对异步依赖的识别。
内容的提问来源于stack exchange,提问作者Ironkinoko
相关产品推荐
相关产品推荐

