webpack生产模式是否会移除挂载在window上的自定义变量和事件监听器?
核心原因
该问题是webpack生产模式默认优化逻辑导致的,主要有两个触发点:
- Tree Shaking 剔除副作用代码:生产模式下webpack默认开启Tree Shaking,会删除判定为无副作用、且未被模块内部引用的代码。入口文件顶层的
window事件绑定、全局属性赋值逻辑没有被内部代码引用,若未声明为副作用代码,会被直接移除。 - Terser 压缩删除无效代码:即使代码未被Tree Shaking剔除,生产模式默认启用的Terser压缩器也会将其判定为无用代码,在压缩阶段删除。你观测到代码存在但未执行的情况,大概率是打包后代码没有被自动执行,比如入口被打包为未自动调用的模块函数。
解决方案
1. 声明入口文件副作用
在项目package.json中添加如下配置,告诉webpack入口文件存在副作用,不可被摇树优化:
{ "sideEffects": [ "./src/index.tsx", "*.css" ] }
也可以在webpack配置的module.rules中针对入口文件设置sideEffects: true。
2. 用立即执行函数包裹挂载逻辑
将全局挂载逻辑包在IIFE(立即执行函数)中,明确告诉压缩器该段代码需要立即运行,不可被删除:
// index.tsx ;(() => { // 事件监听方案 window.addEventListener('renderApp', (event) => { console.log('This is running!'); const { rootId } = event.detail; ReactDOM.render(<App />, document.getElementById(rootId)); }) // 全局函数方案 window.renderApp = (rootId) => { console.log('Child render is running'); ReactDOM.render(<App />, document.getElementById(rootId)); } })()
3. 调整webpack输出配置(微应用场景推荐)
作为被父应用加载的子应用,建议调整webpack输出配置为umd格式,确保产物加载后自动执行,全局挂载逻辑正常生效:
// webpack.config.js module.exports = { output: { // 其余原有配置保持不变 library: 'MySubApp', libraryTarget: 'umd', globalObject: 'this', iife: true } }
验证方式
生产构建完成后,直接打开bundle.js产物搜索renderApp关键词,确认对应逻辑是否存在,同时确认代码被包裹在自动执行的函数块中。
内容的提问来源于stack exchange,提问作者Saad
相关产品推荐
相关产品推荐

