如何让外部加载的脚本在React.lazy生成的所有bundle中正常生效?
问题根因
这个报错的核心原因是jQuery实例不统一:
- 你在index.html通过CDN引入的jQuery和daterangepicker,daterangepicker方法只会挂载到CDN引入的全局
window.jQuery实例上 - 组件中
import $ from 'jquery'引入的是npm安装的jQuery副本,webpack给每个懒加载bundle单独打包了一份jQuery实例,和全局CDN的jQuery不是同一个对象,自然没有挂载daterangepicker方法 - 第一个加载的Dashboard正常是巧合:webpack默认的依赖抽取逻辑只会把先加载的bundle的公共依赖提出来,第二个懒加载bundle拿到的是全新的jQuery副本,没有对应方法
解决方案
方案1(最推荐):配置webpack externals
将已经通过CDN引入的依赖设为外部依赖,不打入bundle,所有组件统一使用全局实例:
- 修改webpack配置(CRA项目未eject可通过craco/customize-cra修改):
module.exports = { // 其余原有配置 externals: { 'jquery': 'jQuery', 'moment': 'moment', 'daterangepicker': 'daterangepicker' } }
配置后组件中的import $ from 'jquery'会直接返回全局的jQuery实例,共享已经挂载的daterangepicker方法。
方案2(无需改构建配置):直接调用全局实例
删除组件中import $ from 'jquery'的代码,直接用全局挂载的$调用方法即可:
useEffect(()=>{ // 直接用window.$调用全局实例 window.$('#datePicker').daterangepicker(initOptions,onCallback) },[])
如果eslint报$未定义,可以在该行上方加// eslint-disable-next-line no-undef注释即可。
方案3:全量走npm引入+公共依赖抽取
完全放弃CDN引入,所有依赖走npm安装,配置webpack抽离公共依赖保证所有组件共享同一份实例:
- 安装依赖:
npm install jquery moment daterangepicker
- 删除index.html中jQuery、moment、daterangepicker相关的CDN script和link标签
- 组件中使用前先导入依赖:
import $ from 'jquery'; import moment from 'moment'; import 'daterangepicker'; import 'daterangepicker/daterangepicker.css'; // 后续调用逻辑不变
- 修改webpack配置,抽离公共依赖:
module.exports = { // 其余原有配置 optimization: { splitChunks: { chunks: 'all', cacheGroups: { common: { name: 'common', minChunks: 2, priority: -20, reuseExistingChunk: true } } } } }
内容的提问来源于stack exchange,提问作者IvanFlavorio
相关产品推荐
相关产品推荐

