Vite主应用集成CRACO+CRA微前端时出现ReactCurrentDispatcher错误
解决Module Federation中ReactCurrentDispatcher未定义的错误
问题背景
我有一个基于CRA创建并添加CRACO的大型React应用,计划逐步拆分为微前端,先搭建Vite主应用,通过路由将流量导向旧应用。已完成主应用(含vite.config.js、package.json、App.tsx)和旧应用(含modulefederation.config.js、.cracorc.js、package.json)的Module Federation配置,两者React、react-dom版本均为18.2.0,但运行时出现错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'ReactCurrentDispatcher')
已排除版本不匹配问题,求可行解决方案。
相关配置代码
主应用配置
vite.config.js
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import federation from '@originjs/vite-plugin-federation'; const deps = require('./package.json').dependencies; export default defineConfig({ plugins: [ react(), federation({ name: 'hostApp', remotes: { legacy_app: { external: 'http://localhost:3333/remoteEntry.js', format: 'var', externalType: 'url', } }, shared: { react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'], }, }, }), ], });
package.json
{ "name": "host-app", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite --port=5500 --strictPort", "build": "vite build", "preview": "vite preview --port=5500 --strictPort" }, "dependencies": { "@originjs/vite-plugin-federation": "1.2.3", "react": "18.2.0", "react-dom": "18.2.0", "react-router-dom": "6.13.0" }, "devDependencies": { "@types/react": "17.0.42", "@types/react-dom": "18.2.6", "@types/react-router": "5.1.20", "@types/react-router-dom": "5.3.3", "@vitejs/plugin-react": "3.1.0", "sass": "1.63.6", "vite": "4.3.9" } }
旧应用配置
modulefederation.config.js
const deps = require("./package.json").dependencies; module.exports = { name: "legacy_app", filename: "remoteEntry.js", exposes: { "./App": "./src/App", }, shared: { react: { singleton: true, requiredVersion: deps.react, }, "react-dom": { singleton: true, requiredVersion: deps["react-dom"], }, }, };
.cracorc.js(部分选项省略)
const cracoModuleFederation = require('craco-module-federation'); module.exports = ({ env }) => { return { plugins: [ { plugin: cracoModuleFederation, }, ] } };
package.json相关依赖
"react": "18.2.0", "react-dom": "18.2.0",
主应用App.tsx
import React, { lazy, Suspense } from "react"; import "./App.css"; import { createBrowserRouter, RouterProvider, } from "react-router-dom"; const LegacyApp = lazy(() => import("legacy_cra/App")); const router = createBrowserRouter([ { path: "/*", element: <LegacyApp/>, }, { path: "/foo", element: <div>Hello world!</div>, } ]); function App() { return ( <Suspense> <RouterProvider router={router}></RouterProvider> </Suspense> ); } export default App;
报错信息
Uncaught TypeError: Cannot read properties of undefined (reading 'ReactCurrentDispatcher') at react-jsx-runtime.development.js:328:1 at ./node_modules/react/cjs/react-jsx-runtime.development.js (react-jsx-runtime.development.js:1313:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./node_modules/react/jsx-runtime.js (jsx-runtime.js:6:1) at options.factory (react refresh:6:1) at __webpack_require__ (bootstrap:24:1) at fn (hot module replacement:62:1) at ./src/App.tsx (ErrorComponents.module.scss:13:1) (anonymous) @ react-jsx-runtime.development.js:328 ./node_modules/react/cjs/react-jsx-runtime.development.js @ react-jsx-runtime.development.js:1313 options.factory @ react refresh:6 __webpack_require__ @ bootstrap:24 fn @ hot module replacement:62 ./node_modules/react/jsx-runtime.js @ jsx-runtime.js:6 options.factory @ react refresh:6 __webpack_require__ @ bootstrap:24 fn @ hot module replacement:62 ./src/App.tsx @ ErrorComponents.module.scss:13 options.factory @ react refresh:6 __webpack_require__ @ bootstrap:24 fn @ hot module replacement:62 (anonymous) @ container-entry:3 (anonymous) @ __x00__virtual:__federation__:82
解决方案
1. 修正远程应用名称不匹配
主应用vite.config.js中配置的remote名称是legacy_app,但App.tsx里导入用的是legacy_cra/App,名称不一致导致加载失败。修改App.tsx的导入语句:
const LegacyApp = lazy(() => import("legacy_app/App"));
2. 共享react/jsx-runtime依赖
ReactCurrentDispatcher错误通常和JSX运行时未正确共享有关,需要在主应用和旧应用的shared配置中添加react/jsx-runtime:
- 主应用vite.config.js的shared部分:
shared: { react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'], }, 'react/jsx-runtime': { singleton: true, requiredVersion: deps.react, }, },
- 旧应用modulefederation.config.js的shared部分:
shared: { react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps["react-dom"], }, 'react/jsx-runtime': { singleton: true, requiredVersion: deps.react, }, },
3. 对齐TypeScript类型依赖版本
主应用devDependencies中@types/react是17.0.42,和React 18.2.0版本不匹配,升级到对应版本:
"@types/react": "18.2.14", "@types/react-router-dom": "6.13.0"
(同时建议把@types/react-router也升级到6.x版本,匹配react-router-dom 6.13.0)
4. 完善旧应用CRACO配置
确保CRACO正确加载Module Federation配置,修改.cracorc.js:
const cracoModuleFederation = require('craco-module-federation'); const moduleFederationConfig = require('./modulefederation.config'); module.exports = ({ env }) => { return { plugins: [ { plugin: cracoModuleFederation, options: { moduleFederationConfig, }, }, ] } };
5. 清理缓存并重启服务
- 删除主应用和旧应用的
node_modules、package-lock.json(或yarn.lock) - 重新安装依赖:
npm install - 分别重启两个应用的开发服务
内容的提问来源于stack exchange,提问作者tdranv
相关产品推荐
相关产品推荐

