Monorepo导入本地包组件时出现dispatcher is null错误求助
Monorepo共享组件导入报错:dispatcher is null
错误信息
dispatcher is null useState@http://localhost:3000/static/js/bundle.js:162692:7 $@http://localhost:3000/static/js/bundle.js:158032:34 renderWithHooks@http://localhost:3000/static/js/bundle.js:114086:31 ...
项目结构
common/ lib/ components/ Tooltip/ index.tsx helpers/ API.ts DATETIME.ts ... index.ts ...configs
index.ts代码
import Tooltip from './components/Tooltip'; export * from './helpers/API'; export * from './helpers/DATETIME'; ... export const COMP = { Tooltip: Tooltip ... }
说明: 将组件包装在该对象中是为了便于后续库的扩展管理。
Tooltip组件代码
import {FC, ReactElement, cloneElement, useState} from 'react'; export interface ITooltipProps { children: ReactElement<any, string>, anchor: ReactElement<any, string> } const Tooltip: FC<ITooltipProps> = (props: ITooltipProps) => { const [isOpen, setIsOpen] = useState(false); return ( <div className='tooltip-wrapper' style={{ position: 'relative', display: 'inline-block' }} onClick={() => setIsOpen(true)} onMouseOver={() => setIsOpen(true)} onMouseLeave={() => setIsOpen(false)} > {cloneElement(props.anchor, {className: 'tooltip-anchor'})} <div style={{ visibility: isOpen ? 'visible' : 'hidden', zIndex: 10, top: '100%', left: '50%', opacity: isOpen ? 1 : 0, transition: 'all ease-in-out 0.3s' }}> {props.children} </div> </div> ) } export default Tooltip;
说明: 当前Tooltip仅作为测试占位组件,用于排查跨包组件导入问题。
package.json配置
... "main": "dist/index.js", "directories": { "lib": "lib" }, "scripts": { "build": "tsup", "ladle": "ladle serve --stories=lib/components/**/*.stories.tsx" }, "devDependencies": { "@ladle/react": "^4.0.2", "@types/react": "^18.2.63", "tsup": "^8.0.2", "typescript": "^5.3.3" }, "dependencies": { "buffer": "^6.0.3" }, "peerDependencies": { "buffer": "^6.0.3", "react": "^18.2.0", "react-dom": "^18.2.0" }
tsconfig.json配置
{ "compilerOptions": { "target": "es2017", "module": "esnext", "lib": [ "esnext", "dom" ], "jsx": "react-jsx", "sourceMap": true, "moduleResolution": "node", "preserveConstEnums": true, "outDir": "./dist", "strict": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "declaration": true } }
tsup.config.json配置
{ "splitting": true, "sourcemap": true, "clean": true, "minify": true, "dts": true, "entry": [ "lib/index.ts" ] }
依赖引入方式
在同仓库的其他项目中,通过"common": "file:../common"将该包添加为依赖。
解决方案
这个错误核心原因是React多实例冲突:common包虽在peerDependencies声明了React,但本地开发时可能安装了独立的React副本,导致主项目和common包使用不同React实例,Hooks无法正常工作。
修复步骤:
阻止
common包打包React
修改tsup.config.json,添加external配置排除React相关依赖,强制复用主项目的React实例:{ "splitting": true, "sourcemap": true, "clean": true, "minify": true, "dts": true, "entry": ["lib/index.ts"], "external": ["react", "react-dom"] }主项目配置React别名(本地开发优化)
若使用Webpack或Vite,配置别名确保所有依赖指向同一React实例:- Webpack示例:
resolve: { alias: { 'react': path.resolve(__dirname, 'node_modules/react'), 'react-dom': path.resolve(__dirname, 'node_modules/react-dom') } } - Vite示例:
export default defineConfig({ resolve: { alias: { 'react': path.resolve(__dirname, './node_modules/react'), 'react-dom': path.resolve(__dirname, './node_modules/react-dom') } } })
- Webpack示例:
清理并重新安装依赖
- 删除
common包和主项目的node_modules - 重新执行
npm install或yarn install
- 删除
验证实例一致性
在主项目中添加测试代码,确认React实例唯一:import React from 'react'; import { COMP } from 'common'; console.log(React === require('common/node_modules/react')); // 输出true表示实例一致
内容的提问来源于stack exchange,提问作者traxx2012
相关产品推荐
相关产品推荐

