You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack打包本地导入npm依赖时React Hook调用报错问题

问题背景

项目通过本地文件链接(file:../widgets)引入npm组件包,使用webpack作为构建工具,引入包内带React Hook的组件时抛出如下错误:

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

react.development.js:1621 Uncaught TypeError: Cannot read properties of null (reading 'useState')
    at useState (react.development.js:1621:21)
    at Button (Button.tsx:25:61)
    at renderWithHooks (react-dom.development.js:16305:18)
    at mountIndeterminateComponent (react-dom.development.js:20069:13)
    at beginWork (react-dom.development.js:21582:16)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:14)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:16)
    at invokeGuardedCallback (react-dom.development.js:4277:31)
    at beginWork$1 (react-dom.development.js:27446:7)
    at performUnitOfWork (react-dom.development.js:26555:12)

已确认的前置信息:

  • 报错涉及的Hook均在函数组件内部调用,组件打包后仍为函数组件,未违反Hook调用规则
  • 组件在本地包独立运行时功能正常,仅在被外部项目引入时触发报错
  • 本地包内未使用React Hook的纯组件,导入主项目后运行无异常
根因定位

该问题由运行时存在多份React实例导致:
本地链接的组件包自身目录下安装了独立的react/react-dom依赖,webpack打包时没有统一复用主项目的React版本,导致组件内调用Hook时,读取的React实例和当前页面渲染用的React实例不是同一个,Hook无法获取正确的组件上下文,最终抛出空指针错误。
纯展示类组件不依赖React的Hook调度上下文,只要能正常解析JSX即可运行,因此不会触发该问题。

可以通过以下命令快速验证是否存在多React副本:
在主项目根目录执行:

npm ls react

如果输出结果中出现多份react条目(分别来自主项目和本地widgets包),即可确认根因。

修复方案

以下方案任选其一即可,推荐优先使用第一种,配置简单不需要修改组件包代码:

方案1:webpack配置强制统一React依赖解析路径

修改主项目的webpack.config.js,在resolve配置项中增加alias,强制所有模块引入的react、react-dom都指向主项目node_modules下的依赖版本,避免打包时引入多份副本:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  // 其他原有配置保持不变
  resolve: {
    extensions: [".tsx", ".ts", ".js", ".css"],
    // 新增以下alias配置
    alias: {
      react: path.resolve(__dirname, "node_modules/react"),
      "react-dom": path.resolve(__dirname, "node_modules/react-dom"),
    },
  },
  // 其他原有配置保持不变
}

方案2:修改组件包依赖声明

进入本地组件包(../widgets)目录,修改自身的package.json:

  1. 将react、react-dom从dependencies配置中移除,添加到peerDependencies中,声明该包需要宿主环境提供对应版本的React依赖,不要自行安装:
    {
      "peerDependencies": {
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
      }
    }
    
  2. 删除组件包目录下的node_modules文件夹和锁文件,回到主项目目录重新执行npm install,之后重新构建即可。

方案3:npm link手动关联React实例

如果是通过npm link方式关联本地包,可以在本地组件包目录下执行以下命令,将包内的react依赖手动指向主项目的react实例:

npm link <主项目绝对路径>/node_modules/react
npm link <主项目绝对路径>/node_modules/react-dom

该方法每次重新安装依赖后需要重新执行link操作,稳定性弱于前两种方案。

修复完成后重启webpack开发服务/重新打包,引入的带Hook组件即可正常运行。


内容的提问来源于stack exchange,提问作者Kristóf Göncző

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 11:36:18