Reactjs 在应用程序和私有库中包含React的正确方法是什么?(来自重复React的React无效钩子调用警告)

Reactjs 在应用程序和私有库中包含React的正确方法是什么?(来自重复React的React无效钩子调用警告),reactjs,typescript,parceljs,Reactjs,Typescript,Parceljs,我有一种“monorepo”,一个由几个使用React的小项目组成的大项目 我试图将它们分为三个独立的存储库,分别称为Core、Application1和Application2 Core是两个应用程序的依赖项,而Core依赖于React,因为它定义了一些React组件类。这两个应用程序都使用React 当我尝试一起构建这个包时(使用Parcel bundler),我得到了最后一个包,它在运行时在一个(但不是两个)应用程序中给出警告 在该页面上(或在错误消息中),它指出错误可能由以下原因之一引起

我有一种“monorepo”,一个由几个使用React的小项目组成的大项目

我试图将它们分为三个独立的存储库,分别称为
Core
Application1
Application2

Core
是两个应用程序的依赖项,而
Core
依赖于React,因为它定义了一些React组件类。这两个应用程序都使用React

当我尝试一起构建这个包时(使用Parcel bundler),我得到了最后一个包,它在运行时在一个(但不是两个)应用程序中给出警告

在该页面上(或在错误消息中),它指出错误可能由以下原因之一引起:

  • 您可能有不匹配的React和React DOM版本
  • 你可能违反了钩子的规则
  • 同一应用程序中可能有多个React副本
  • 我已经检查过#1不是真的,而且我甚至没有以我所知道的任何方式使用钩子,所以问题似乎是React的多个版本

    通过阅读本文,我发现我的
    Core
    库将React声明为依赖项是一个错误,它应该在
    peerDependencies
    中声明它。这使应用程序停止给出错误,但也使我的核心库开始出现一系列类型脚本错误,并且无法运行单元测试(依赖于React,使用Jest/Enzyme来呈现和验证DOM)

    由于在
    peerDependencies
    中指定React导致它没有安装在
    Core
    节点模块中,我决定我可能应该在
    peerDependencies
    Core
    devDependencies
    中包含React。这再次修复了核心库,但破坏了应用程序

    我不太确定以下几点:

    • 为什么我的一个应用程序由于复制而失败,而另一个没有,因为它们看起来彼此非常对称
    • 为什么,即使我只在
      peerDependencies
      中指定React,在
      Core
      中指定
      devdependencies
      ,我仍然会在从属应用程序中获得React的副本

    • 核心
      引入应用程序的方法是否与此相关。(我正在尝试的一种方法是package.json,我将core指定为URL的“file:../”样式。另一种方法是使用“纱线链接”,或者可能同时使用这两种方法,我不确定这是否会对应用程序文件夹下的
      节点模块中的内容产生任何影响,或者对绑定的内容产生任何影响)

    在应用程序和库中都包含React的正确方法是什么?这样,这两个项目都可以使用React,但应用程序中的重复项不会导致此钩子错误(或者,只是占用额外的空间)。

    回答我自己的问题

    我发现以下问题很有帮助:

    在对解决此问题的方法的评论中提出了各种不同的建议,可以通过
    npm-link
    warn-link
    将react库从库转移到应用程序,或者反之亦然。这些似乎都是有希望的,因为这样做的目的是确保所有不同的引用都指向同一个地方。不幸的是,这些都不适合我。(例如,JerryGreen和Kas在该问题上的回答)

    另一个用户dcecile建议使用webpack的
    别名
    功能,但我没有使用webpack

    resolve: {
        alias: { react: require.resolve("react") }
    },
    
    Parcel具有类似的
    别名
    功能,但不能以完全相同的方式使用,因为它在package.json文件中使用,所以像
    这样的东西需要.resolve不能像在webpack的js配置文件中那样调用

    根据用户jaredpalmer的另一个例子,我最终找到了一种使用Parcel的
    别名
    功能来做我想做的事情的方法。在我的情况下,我将它添加到应用程序的package.json中,它似乎消除了复制问题和“无效钩子调用”错误:


    您是否在Windows上?@Keith有时是,有时不是。无论操作系统“用于将Core引入应用程序的方法是否与此相关”,都会遇到相同的问题@jared如前所述,应用程序正在使用package.json相对文件引用引入Core,例如,
    “我的Core库”:“文件:../my Core库”
    。我这样做是因为我不打算将核心包发布到npm。但是我希望能够同时开发Core和应用程序,简单地使用相对文件引用是有问题的,因为它是一个副本,所以应用程序不会不断地得到Core源代码的更改,这就是为什么我也一直在使用
    纱线链接
    ,它允许核心更改立即传播到应用程序
     "alias": {
        "react": "../my-core-library/node_modules/react",
      },