Webpack Encore + Symfony 如何让base加载的common.js模块对子视图生效
报错原因
Webpack 原生开启模块化隔离,所有在模块内导入的依赖默认仅存在于当前模块的局部作用域,不会自动挂载到全局window对象上。你在子视图中编写的内联JS运行在全局作用域,自然无法访问common.js模块内部导入的ResizeSensor变量。
适配方案(符合你不想对所有库做全局导入配置的需求)
方案1:common.js内手动挂载需要暴露的依赖(推荐,改动最小)
不需要修改任何Webpack配置,仅需要在common.js中自行控制要暴露到全局的依赖,不需要暴露的库不会污染全局空间:
// common.js 调整后的写法 // 1. 改为命名导入,拿到库导出的构造函数/方法 import ResizeSensor from 'resize-sensor'; // 其他需要暴露到全局的通用库同理导入 import OtherLib from 'other-lib'; // 2. 手动挂载到window全局对象 window.ResizeSensor = ResizeSensor; window.OtherLib = OtherLib; // 若想减少全局变量污染,也可以统一挂载到自定义命名空间 window.CommonUtils = window.CommonUtils || {}; window.CommonUtils.ResizeSensor = ResizeSensor; // 子视图调用时写法为 new CommonUtils.ResizeSensor(...)
注意:你原有
import 'resize-sensor'的写法仅会执行库的初始化代码,无法拿到库导出的构造函数,必须改为带变量名的导入语法。
方案2:批量配置暴露规则(适合大量通用库需要暴露的场景)
如果需要暴露的通用库数量较多,不想挨个写挂载代码,可以在Webpack配置中一次性添加规则:
// webpack.config.js 原有配置基础上添加loader规则 Encore // 其他原有配置保持不变 .addLoader({ test: require.resolve('resize-sensor'), loader: 'expose-loader', options: { exposes: ['ResizeSensor'] } }) // 其他需要暴露的库按相同格式追加配置即可
注意事项
- 确保base.html.twig中
{{ encore_entry_script_tags('common') }}的调用位置在所有子视图内联JS的上方,避免加载顺序错误导致的未定义问题 - 如果后续你要逐步迁移内联JS到Encore管理的独立JS模块,不需要挂载全局,直接在对应模块中导入所需依赖即可使用
内容的提问来源于stack exchange,提问作者Alberto Posada
相关产品推荐
相关产品推荐

