You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Module Federation + React Vite环境下React-Three-Fiber画布加载失败:Cannot read properties of undefined (reading 'current')

Module Federation + React Vite环境下React-Three-Fiber画布加载失败:Cannot read properties of undefined (reading 'current')

看起来你遇到的是 Module Federation 共享依赖时,React Three Fiber (R3F) 的 ref 上下文被破坏的典型问题——我之前在做类似的3D微前端项目时也踩过这个坑,来帮你拆解下可能的原因和解决办法:

可能的核心原因

这个错误本质上是 R3F/Three.js 出现了多实例冲突,导致 Canvas 组件依赖的 ref 无法正确绑定到单例的上下文上。虽然你已经在共享配置里设置了 singleton: true,但实际生效过程中可能因为版本匹配、加载时机或配置遗漏,导致 Host 和 Remote 端加载了不同的 R3F/Three.js 实例,进而破坏了 ref 的引用链路。

逐步排查与修复方案

1. 先验证共享依赖的单实例是否真的生效

首先要确认 Host 和 Remote 端使用的是同一个 R3F/Three.js 实例,这是问题的关键:

  • 在 Host 和 Remote 应用的控制台分别执行以下代码,打印共享实例的引用:
    // 检查 R3F 实例
    console.log('R3F Instance:', window.__federation_shared__?.['@react-three/fiber']?.instance);
    // 检查 Three.js 实例
    console.log('Three Instance:', window.__federation_shared__?.three?.instance);
    
  • 如果两端打印的引用地址不一致,说明共享配置没真正生效,需要先解决这个问题。

2. 统一两端的共享配置(关键!)

很多人会忽略:Remote 端的共享配置必须和 Host 端完全对齐,不能只在 Host 里配置共享。

在 Remote 项目的 vite.config.js 中,必须添加完全相同的共享规则:

shared: {
  react: { singleton: true, requiredVersion: "^18.0.0" },
  "react-dom": { singleton: true, requiredVersion: "^18.0.0" },
  "@react-three/fiber": { singleton: true, requiredVersion: "^8.9.1" },
  "three": { singleton: true, requiredVersion: "0.146.0" },
  // 其他你需要共享的依赖...
}

Module Federation 是双向协商的,只有两端都同意共享某个依赖,才能真正实现单实例复用。

3. 给 R3F/Three.js 添加 eager: true 配置

R3F 和 Three.js 对加载时机比较敏感,懒加载的共享模块可能导致初始化时上下文丢失。尝试在 Host 和 Remote 的共享配置中给这两个包加上 eager: true

"@react-three/fiber": { 
  singleton: true, 
  requiredVersion: "^8.9.1",
  eager: true // 强制启动时就加载共享实例
},
"three": { 
  singleton: true, 
  requiredVersion: "0.146.0",
  eager: true
},

4. 强制锁定依赖版本,避免隐性多实例

即使你说两端用了相同版本,也可能因为包管理器的版本解析规则(比如 ^ 符号),导致实际安装的版本有细微差异。可以通过版本锁定来解决:

  • 在 Host 和 Remote 的 package.json 中添加版本覆盖规则:
    // npm 使用 overrides,pnpm/yarn 使用 resolutions
    "overrides": {
      "three": "0.146.0",
      "@react-three/fiber": "8.9.1"
    }
    
  • 执行 npm install/pnpm install/yarn install 重新安装依赖,确保所有嵌套依赖的版本都被统一。

5. 验证 React 上下文的一致性

R3F 严重依赖 React 的上下文机制,所以还要确认 React/ReactDOM 的单实例是否正常:

  • 在控制台执行以下代码,检查是否为同一个实例:
    console.log('React 实例一致?', React === window.__federation_shared__?.react?.instance);
    console.log('ReactDOM 实例一致?', ReactDOM === window.__federation_shared__?.['react-dom']?.instance);
    
    如果返回 false,说明 React/ReactDOM 的共享也有问题,需要先修复这个基础依赖的共享。

最后总结排查流程

按照这个顺序排查,大概率能解决问题:

  1. 确保 Host 和 Remote 的共享配置完全一致
  2. 验证所有核心依赖(React/ReactDOM/R3F/Three)的单实例是否生效
  3. 强制锁定依赖版本,消除隐性版本差异
  4. 尝试给 R3F/Three 添加 eager: true 配置

如果还是不行,可以尝试一个简化测试:暂时移除 Remote 中所有和 3D 相关的代码,只加载一个纯 React 组件,看是否还会触发错误。如果错误消失,说明 Remote 端的 3D 组件也需要适配共享配置;如果错误依然存在,那大概率是基础共享配置的问题。

希望这些步骤能帮你解决问题,有新的排查结果可以随时补充~

火山引擎 最新活动