Vite构建React组件库npm link时报Invalid hook call错误如何解决
Vite打包React组件库npm link后useContext报错问题
问题背景
此前使用Rollup可正常完成React组件库打包,为使用Vite的开发特性,将构建工具更换为Vite。通过npm link将Vite生成的构建产物关联到其他React项目时出现报错:
报错核心表现为:加载React Context对应的Provider组件时无法使用useContext,构建产物加载到对应位置时出现异常,产物中对应代码段如下:
var Context=/*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);
当前使用的Vite配置如下:
export default defineConfig({ plugins: [react(), dts({ insertTypesEntry: true })], build: { lib: { entry: path.resolve(__dirname, "src/lib/index.ts"), name: "MyLib", formats: ["umd", "es"], fileName: (format) => `my-lib.${format}.js`, }, rollupOptions: { external: [ "react", "react-dom" ] } }, });
已做的排查尝试:
- 检索资料得知该类错误可能由依赖问题导致,比如项目中存在多版本react或react-dom,已尝试所有可想到的依赖配置方案,均出现不同形式的报错
- 排查过npm缓存导致异常的可能性
- Vite的dev模式运行完全正常,相同组件代码此前用Rollup打包也可正常使用,判断为遗漏Vite配置项导致的问题
解决方案
按以下步骤修改配置即可修复:
- 补全Rollup外部依赖的全局变量映射
当前配置仅声明了react、react-dom为外部依赖,但未给UMD格式配置对应的全局变量名,会导致UMD产物无法正确引用宿主项目的React实例。修改rollupOptions配置如下:
rollupOptions: { // 同时把jsx运行时也加入外部依赖,避免Vite默认的JSX运行时被打包进产物 external: [ "react", "react-dom", "react/jsx-runtime", "react-dom/client" ], output: { globals: { react: "React", "react-dom": "ReactDOM", "react/jsx-runtime": "react/jsx-runtime", "react-dom/client": "ReactDOM" } } }
- 配置别名强制统一React引用路径,解决npm link场景下的多React实例问题
npm link的软链接机制会导致依赖查找时出现多份React实例,这是hooks调用报错的核心原因。在Vite配置中添加resolve别名配置,强制所有React相关引用都指向组件库本地node_modules下的依赖:
import path from 'path' // 配置根节点添加 resolve: { alias: { react: path.resolve(__dirname, "./node_modules/react"), "react-dom": path.resolve(__dirname, "./node_modules/react-dom") } }
- 修正package.json依赖声明
将react、react-dom从dependencies移动到peerDependencies中,声明为宿主需要提供的依赖,避免npm安装时在组件库目录下重复安装React:
{ "peerDependencies": { "react": ">=17.0.0", "react-dom": ">=17.0.0" } }
配置修改完成后,删除组件库和测试项目的dist目录、node_modules目录、锁文件,重新执行依赖安装、构建、link操作,排除旧缓存的干扰。
内容的提问来源于stack exchange,提问作者DeveloperOfMrPibb
相关产品推荐
相关产品推荐

