如何在pnpm Monorepo中实现React与Preact应用共享组件?
解决思路与优化方案
一、先排查preact/compat的配置问题
你遇到的cannot read property undefined of current错误,大多是React和Preact的上下文映射没做好,或是依赖解析优先级冲突,按下面步骤排查:
- 统一Monorepo依赖规则:在
pnpm-workspace.yaml里给所有子包配置peerDependenciesMeta,把react和preact设为可选;同时组件库的package.json里,peerDependencies要包含react、react-dom、preact、preact/compat,防止重复安装导致冲突。 - 调整Vite解析别名:
在React应用的vite.config.js里,把React相关包映射到preact/compat:
Preact应用不用额外映射,但要确保export default { resolve: { alias: { 'react': 'preact/compat', 'react-dom': 'preact/compat' } } }preact/compat已安装,组件库导入时优先用Preact核心包。 - 组件库打包配置:如果用Vite打包组件库,要在
build.lib里把['react', 'react-dom', 'preact', 'preact/compat']设为external,别把React/Preact打包进组件库,让宿主应用提供这些依赖。
二、更优方案:基于Preact开发组件库,双入口适配双环境
直接用Preact写组件库,打包时生成两个入口,分别对应Preact原生和React兼容场景:
- 组件源码用Preact语法:所有组件都用
import { h, Component } from 'preact'编写,别用React独有的API。 - 配置Vite双入口打包:在组件库的
vite.config.js里设置两个入口:
其中export default { build: { lib: { entry: { preact: './src/index-preact.js', // Preact应用直接用 react: './src/index-react.js' // React应用用的兼容入口 }, formats: ['es', 'cjs'] } } }index-react.js只需做一层包装,确保用preact/compat的上下文:import * as components from './components'; import { createElement } from 'preact/compat'; Object.keys(components).forEach(key => { if (typeof components[key] === 'function') { const original = components[key]; components[key] = (...args) => createElement(original, ...args); } }); export default components; - 宿主应用按需导入:React应用直接导入
your-library/react,Preact应用导入your-library/preact,不用额外配置映射,彻底避免上下文冲突。
三、额外注意点
- 避开React独有API:比如用Preact的
createContext替代React的,两者语法兼容;如果要用useId这类新API,确保preact/compat版本在10.10.0以上。 - 双环境测试:在Monorepo里同时启动React和Preact应用,分别导入组件库测试,及时发现环境专属问题。
内容的提问来源于stack exchange,提问作者llccrr
相关产品推荐
相关产品推荐

