拥有多个 React 实例是什么意思?

What does it mean to have multiple instances of React?

对于上下文:我在我的 React 应用程序(使用 npm + Create React App + TypeScript)中遇到了一个问题,我的应用程序中似乎有多个 React 副本。这是基于 React documentation 中给出的诊断片段,您在其中测试 window.React1 === window.React2.

这个问题不是要求解决这个问题的解决方案(我将单独调查)。相反,我想知道 意味着 有一个库的副本。这最终如何作为 CRA 生成的大型捆绑脚本的一部分传送到浏览器,以及当我在源代码中编写 import React from 'react' 时选择了哪个副本?重复库是如何发生的,为什么 npm 允许这样?

答案可能是,“去了解 JS 包管理和捆绑是如何工作的”,这可能是非常合理的,但如果有人有任何具体的答案和指向更多学习资源的指针,我会非常感谢。 TIA.

首先,让我们清楚地说明重复库在这种情况下的含义。如果你要解压你的捆绑项目,你可能会发现 React 的多个版本,例如 16 和 17。这是一个很好的框架,在接下来的讨论中要记住。

虽然大多数情况下,这种重复是错误的,但在某些情况下这可能是可取的。在讨论您的具体案例之前,让我们先介绍一下。

使用类似于 the micro frontends architecture 的东西的大型分布式开发团队就是一个很好的例子,它可以从中受益。简而言之,两个团队可能负责页面的两个不同部分,它们具有自己的一组依赖关系,而不会影响另一个:

 ┌───────────────────────────┐
 │          Webpage          │
 │ ┌──────────┐ ┌──────────┐ │
 │ │ React 16 │ │ React 17 │ │
 │ └──────────┘ └──────────┘ │
 └───────────────────────────┘

虽然这看起来像是浪费 space,但开发团队在这里做出了权衡:他们的页面负载稍大,但减少了团队间同步版本的需要。也许一个团队已准备好使用最新版本,但另一个团队在准备更新之前仍需要做一些工作。另一个很好的例子是遗留代码——你可能有运行良好的代码,但没有维护,所以你选择只要它能运行就按原样发布:

 ┌──────────────────────────────┐
 │           Webpage            │
 │ ┌───────────┐ ┌────────────┐ │
 │ │ Angular 1 │ │ Angular 10 │ │
 │ └───────────┘ └────────────┘ │
 └──────────────────────────────┘

希望以上说明了为什么包管理器允许这样的设置:它们可能是可取的,并且在某些情况下非常有益。

设置的方式与项目设置一样广泛,但上述方法之一是拥有某种子项目,每个子项目都有自己的 package.json:

project
├─ package.json
├─ one subproject
│  └─ package.json
└─ another subproject
   └─ package.json

在上述情况下,one subproject 中的导入将设置为由该文件夹中的 package.json 解析,而 another subproject 中的导入将设置为其解析package.json。配置模块分辨率的一种常见方法是通过 Webpack resolve configuration,但其他方法当然也是可能的。

希望上面的内容解释了为什么这是可能的,以及一些关于何时可能是一个好的考虑的提示。

尽管如前所述,大多数时候这是一个错误。大多数用户并不是有意这样做的,并且包括具有微小差异的相同库,例如 React 17.0.0 和 React 17.0.1 并不是他们想要做的。对于常见的用例,以上两者实际上应该可以互换。

有多种方法可以解决此问题,但最常见的方法是配置不正确 peer dependencies。对等依赖是库、组件包等指定它们所依赖的内容的一种方式,同时允许共享依赖。一个常见的例子是 UI 组件库,它支持任何 React 版本,只要它比 React 16 更新。如果你的项目使用 React 17,你可以愉快地引入该组件库并拥有一个代码库中的 React 版本。

当库作者(无意中)将对 React 16 的依赖项配置为常规依赖项而不是对等依赖项时,就会发生错误。在这种情况下,作者基本上是在说库需要 React 16 并且不允许其他任何东西,你最终会安装两个版本的 React。

以上所有内容都非常笼统,忽略了很多细节,但希望这能让您对正在解决的问题有所了解。