版本策略
所有 React 的稳定版本都经过了高度的测试并遵循语义化版本控制 (semver)。React 还提供不稳定的发布渠道,以鼓励对实验性功能的早期反馈。本页介绍了您对 React 版本发布的期望。
有关先前版本列表,请参阅 版本 页面。
稳定版本
稳定 React 版本(也称为“最新”发布渠道)遵循 语义化版本控制 (semver) 原则。
这意味着使用版本号 x.y.z
- 在发布 关键错误修复时,我们会通过更改 z 号来进行 补丁发布(例如:15.6.2 到 15.6.3)。
- 在发布 新功能或 非关键修复时,我们会通过更改 y 号来进行 次要发布(例如:15.6.2 到 15.7.0)。
- 在发布 重大变更时,我们会通过更改 x 号来进行 主要发布(例如:15.6.2 到 16.0.0)。
主要版本也可以包含新功能,任何版本都可以包含错误修复。
次要版本是最常见的发布类型。
重大变更
重大变更对每个人来说都很麻烦,所以我们尽量减少主要版本的数量 - 例如,React 15 于 2016 年 4 月发布,React 16 于 2017 年 9 月发布,React 17 于 2020 年 10 月发布。
相反,我们在次要版本中发布新功能。这意味着次要版本通常比主要版本更有趣,更令人信服,尽管它们的名字不那么引人注目。
稳定性承诺
随着时间的推移,我们对 React 进行更改,我们会尽量减少利用新功能所需的努力。在可能的情况下,我们会保持旧 API 的工作,即使这意味着将其放在单独的包中。例如,混合已被多年抵制,但它们至今仍受到支持 通过 create-react-class,并且许多代码库继续在稳定的遗留代码中使用它们。
超过一百万的开发人员使用 React,共同维护着数百万个组件。仅 Facebook 代码库就拥有超过 50,000 个 React 组件。这意味着我们需要尽可能地简化升级到 React 新版本的流程;如果我们在没有迁移路径的情况下进行重大更改,人们将停留在旧版本上。我们在 Facebook 本身测试了这些升级路径 - 如果我们不到 10 人的团队可以单独更新 50,000 多个组件,我们希望升级对任何使用 React 的人都可以管理。在许多情况下,我们编写了 自动化脚本 来升级组件语法,然后将其包含在开源版本中,供所有人使用。
通过警告逐步升级
React 的开发版本包含许多有用的警告。在可能的情况下,我们添加警告以准备未来的重大变更。这样,如果您的应用程序在最新版本上没有警告,它将与下一个主要版本兼容。这允许您一次升级一个组件。
开发警告不会影响应用程序的运行时行为。这样,您可以确信您的应用程序在开发和生产版本之间将具有相同的行为 - 唯一的区别是生产版本不会记录警告,并且效率更高。(如果您发现情况并非如此,请提交问题。)
什么算作重大变更?
一般来说,我们不会为以下更改更改主要版本号
- 开发警告。由于这些不会影响生产行为,因此我们可能会在主要版本之间添加新的警告或修改现有警告。事实上,这就是我们能够可靠地警告即将发生的重大变更的原因。
- 以
unstable_
开头的 API。这些提供为实验性功能,我们尚未对它们的 API 有信心。通过在unstable_
前缀下发布这些,我们可以更快地迭代,并尽快获得稳定的 API。 - React 的 Alpha 和 Canary 版本。我们提供 React 的 alpha 版本,以便尽早测试新功能,但我们需要灵活地根据我们在 alpha 阶段的学习结果进行更改。如果您使用这些版本,请注意 API 可能会在稳定版本发布之前发生更改。
- 未记录的 API 和内部数据结构。如果您访问内部属性名称,如
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
或__reactInternalInstance$uk43rzhitjg
,则没有保证。您需要自担风险。
此策略旨在实用:当然,我们不想给您带来麻烦。如果我们为所有这些更改提升主要版本号,我们将最终发布更多主要版本,并最终给社区带来更多版本控制方面的困扰。这也意味着我们无法像我们希望的那样快地改进 React。
也就是说,如果我们预计该列表中的更改会导致社区出现广泛问题,我们仍将尽最大努力提供逐步迁移路径。
如果一个小版本发布没有包含新功能,为什么它不是一个补丁?
一个小版本发布可能不会包含新功能。 semver 允许这样做,它指出 “[次要版本] 可以在私有代码中引入重大新功能或改进时递增。 它可以包含补丁级别的更改。”
然而,这确实提出了一个问题,为什么这些版本没有作为补丁进行版本控制。
答案是,对 React(或其他软件)的任何更改都存在以意想不到的方式破坏的风险。 想象一下这样一种情况,一个修复一个错误的补丁版本意外地引入了另一个错误。 这不仅会扰乱开发人员,还会损害他们对未来补丁版本的信心。 如果原始修复是针对实际上很少遇到的错误,则尤其令人遗憾。
我们在保持 React 版本没有错误方面有很好的记录,但补丁版本对可靠性的要求更高,因为大多数开发人员都认为他们可以在没有负面影响的情况下采用这些版本。
出于这些原因,我们只将补丁版本保留用于最严重的错误和安全漏洞。
如果一个版本包含非必要的更改——例如内部重构、对实现细节的更改、性能改进或小错误修复——我们将提升次要版本,即使没有新功能。
所有发布渠道
React 依赖于一个蓬勃发展的开源社区来提交错误报告、打开拉取请求和 提交 RFC。 为了鼓励反馈,我们有时会分享包含未发布功能的 React 特别版本。
React 的每个发布渠道都针对不同的用例而设计
- 最新 用于稳定、semver React 版本。 这是你从 npm 安装 React 时获得的版本。 这是你今天正在使用的渠道。 直接使用 React 的面向用户应用程序使用此渠道。
- 金丝雀 跟踪 React 源代码库的主分支。 可以将它们视为下一个 semver 版本的发布候选版本。 框架或其他经过精心策划的设置可以选择使用此渠道并固定 React 的版本。 你也可以使用 Canaries 进行 React 和第三方项目之间的集成测试。
- 实验性 包括实验性 API 和功能,这些 API 和功能在稳定版本中不可用。 它们也跟踪主分支,但打开了额外的功能标志。 使用它在功能发布之前尝试它们。
所有版本都发布到 npm,但只有 Latest 使用语义版本控制。 预发布版本(那些在 Canary 和 Experimental 渠道中的版本)的版本是从其内容和提交日期的哈希值生成的,例如 18.3.0-canary-388686f29-20230503
用于 Canary 和 0.0.0-experimental-388686f29-20230503
用于 Experimental。
Latest 和 Canary 渠道都正式支持面向用户的应用程序,但预期不同:
- Latest 版本遵循传统的 semver 模型。
- Canary 版本 必须固定 并且可能包含破坏性更改。 它们存在于希望根据自己的发布计划逐步发布新的 React 功能和错误修复的经过精心策划的设置(如框架)中。
实验性版本仅用于测试目的,我们不保证版本之间不会发生行为改变。 它们不遵循我们用于 Latest 版本的 semver 协议。
通过将预发布版本发布到与我们用于稳定版本的同一个注册表,我们能够利用许多支持 npm 工作流程的工具,例如 unpkg 和 CodeSandbox。
Latest 渠道
Latest 是用于稳定 React 版本的渠道。 它对应于 npm 上的 latest
标签。 它是所有发布到真实用户的 React 应用程序的推荐渠道。
如果你不确定应该使用哪个渠道,那就是 Latest。 如果你直接使用 React,这就是你正在使用的。 你可以预期 Latest 的更新将非常稳定。 版本遵循语义版本控制方案,如 之前所述。
Canary 渠道
Canary 渠道是一个预发布渠道,它跟踪 React 存储库的主分支。 我们使用 Canary 渠道中的预发布版本作为 Latest 渠道的发布候选版本。 你可以将 Canary 视为 Latest 的超集,它更新更频繁。
最新 Canary 版本和最新 Latest 版本之间的变化程度与你在两个次要 semver 版本之间发现的程度大致相同。 然而,Canary 渠道不符合语义版本控制。 你应该预期 Canary 渠道中连续版本之间偶尔会有破坏性更改。
不要直接在面向用户的应用程序中使用预发布版本,除非你遵循 Canary 工作流程。
Canary 中的版本发布带有 npm 上的 canary
标签。 版本是从构建内容和提交日期的哈希值生成的,例如 18.3.0-canary-388686f29-20230503
。
将 canary 渠道用于集成测试
Canary 渠道也支持 React 与其他项目之间的集成测试。
所有对 React 的更改都会经过广泛的内部测试,然后再发布给公众。 然而,React 生态系统中使用了无数的环境和配置,我们不可能对每一个进行测试。
如果你是一位第三方 React 框架、库、开发工具或类似基础设施类型项目的作者,你可以通过定期对最新更改运行你的测试套件来帮助我们保持 React 对你的用户和整个 React 社区的稳定性。 如果你有兴趣,请按照以下步骤操作
-
使用你喜欢的持续集成平台设置一个 cron 作业。 Cron 作业同时受 CircleCI 和 Travis CI 支持。
-
在 cron 任务中,使用 npm 上的
canary
标签,将你的 React 包更新到 Canary 通道中最新的 React 版本。使用 npm clinpm update react@canary react-dom@canary或 yarn
yarn upgrade react@canary react-dom@canary -
针对更新后的包运行你的测试套件。
-
如果一切顺利,那就太好了!你可以期待你的项目能够与下一个次要的 React 版本一起工作。
-
如果出现意外错误,请通过 提交问题 告知我们。
使用此工作流程的项目是 Next.js。你可以参考他们的 CircleCI 配置 作为示例。
实验性通道
与 Canary 相似,实验性通道是一个预发布通道,跟踪 React 存储库的主分支。与 Canary 不同的是,实验性版本包含尚未准备好广泛发布的其他功能和 API。
通常,对 Canary 的更新会伴随对实验性的相应更新。它们基于相同的源代码版本,但使用不同的功能标志集进行构建。
实验性版本可能与 Canary 和 Latest 版本有很大不同。 不要在面向用户的应用程序中使用实验性版本。 你应该预期实验性通道中的版本之间会频繁出现重大更改。
实验性版本发布时使用 npm 上的 experimental
标签。版本从构建内容和提交日期的哈希值生成,例如 0.0.0-experimental-68053d940-20210623
。
哪些内容会进入实验性版本?
实验性功能是尚未准备好发布给更广泛公众的功能,它们在最终确定之前可能会发生巨大的变化。一些实验可能永远不会最终确定 - 我们进行实验的目的是测试所提议更改的可行性。
例如,如果在宣布 Hooks 时存在实验性通道,我们将把 Hooks 发布到实验性通道,并在它们在 Latest 中可用之前几周发布。
你可能会发现针对 Experimental 运行集成测试很有价值。这取决于你。但是,请注意,Experimental 比 Canary 更加不稳定。 我们不保证 Experimental 版本之间的任何稳定性。
我如何了解更多关于实验性功能的信息?
实验性功能可能已被记录,也可能尚未记录。通常,实验在 Canary 或 Latest 中即将发布之前才会被记录。
如果某项功能没有记录,它可能附带一个 RFC.
当我们准备好宣布新的实验时,我们将在 React 博客 上发布消息,但这并不意味着我们会公布每个实验。
你始终可以参考我们公共 GitHub 存储库的 历史记录 获取所有更改的综合列表。