React Canary 版本:在 Meta 之外启用增量特性发布
2023年5月3日 作者:Dan Abramov、Sophie Alpert、Rick Hanlon、Sebastian Markbåge 和 Andrew Clark
我们希望为 React 社区提供一个选项,以便在稳定版本发布之前,尽早采用单个新特性,前提是其设计已接近最终状态——这与 Meta 内部长期使用 React 最前沿版本的方式类似。我们正在引入一个新的官方支持的 Canary 发布渠道。它允许像框架这样的精选设置将单个 React 特性的采用与 React 发布计划解耦。
tl;dr
- 我们正在为 React 引入一个官方支持的 Canary 发布渠道。由于它是官方支持的,如果出现任何回归问题,我们将以与稳定版本中的错误相同的紧迫性对待它们。
- Canary 版本允许您在新的 React 特性进入语义版本控制稳定版本之前就开始使用它们。
- 与 实验性 渠道不同,React Canary 版本只包含我们合理认为已准备好采用的特性。我们鼓励框架考虑捆绑固定版本的 Canary React 版本。
- 当 Canary 版本中出现重大更改和新特性时,我们会通过博客公布。
- 与以往一样,React 继续遵循语义版本控制 (semver) 的规范来发布每一个稳定版本。
React 特性的开发流程
通常,每个 React 特性都经历了相同的阶段
- 我们开发初始版本,并在其前面添加前缀
experimental_
或unstable_
。该特性仅在experimental
发布渠道中可用。在此阶段,该特性预计会发生重大更改。 - 我们会在 Meta 找到一个团队来帮助我们测试此特性,并提供反馈。这会导致一轮更改。随着特性的稳定性提高,我们会与 Meta 的更多团队合作来试用它。
- 最终,我们对设计充满信心。我们从 API 名称中删除前缀,并默认情况下在
main
分支上启用该特性,大多数 Meta 产品都使用该分支。此时,Meta 的任何团队都可以使用此特性。 - 随着我们对方向的信心增强,我们还会发布新特性的 RFC。此时,我们知道该设计适用于广泛的情况,但我们可能会进行一些最后的调整。
- 当我们接近发布开源版本时,我们会为该特性编写文档,并最终在稳定的 React 版本中发布该特性。
此流程对我们迄今为止发布的大多数特性都非常有效。但是,特性普遍可以使用(步骤 3)与在开源中发布(步骤 5)之间可能存在显著的时间差。
我们希望为 React 社区提供一个选项,以便遵循与 Meta 相同的方法,尽早采用单个新特性(一旦可用),而无需等待下一个 React 发布周期。
与以往一样,所有 React 特性最终都会进入稳定版本。
我们能否只进行更多小版本发布?
通常,我们确实使用小版本发布来引入新特性。
但是,这并非总是可行。有时,新特性与尚未完全完成且我们仍在积极迭代的*其他*新特性相互关联。我们无法分别发布它们,因为它们的实现是相关的。我们无法分别对它们进行版本控制,因为它们会影响相同的包(例如,react
和 react-dom
)。我们需要保持在不进行大量主要版本发布(语义版本控制需要我们这样做)的情况下迭代未准备好部分的能力。
在 Meta,我们通过从 main
分支构建 React,并每周手动将其更新到特定的固定提交来解决这个问题。这也是 React Native 在过去几年中一直遵循的方法。React Native 的每个*稳定*版本都固定在 React 代码库的 main
分支中的特定提交上。这允许 React Native 包含重要的错误修复,并在框架级别增量地采用新的 React 特性,而无需与全局 React 发布计划耦合。
我们希望将此工作流程提供给其他框架和精选的设置。例如,它允许一个基于React的框架在破坏性更改包含到稳定的React版本之前包含一个与React相关的破坏性更改。这尤其有用,因为某些破坏性更改只会影响框架集成。这允许框架在其自己的次要版本中发布此类更改,而不会破坏语义版本控制。
使用Canary通道的滚动发布将使我们能够拥有更紧密的反馈循环,并确保新功能在社区中得到全面的测试。此工作流程更接近于JavaScript标准委员会TC39 处理分阶段更改的方式。新的React功能可能在基于React的框架中可用,然后才在稳定的React版本中可用,就像新的JavaScript功能在浏览器中发布然后才正式批准为规范的一部分一样。
为什么不使用实验性版本?
虽然您可以在技术上使用 实验性版本,但我们建议不要在生产环境中使用它们,因为实验性API在稳定化的过程中可能会发生重大破坏性更改(甚至可能被完全删除)。虽然Canary版本也可能包含错误(与任何版本一样),但展望未来,我们计划在我们的博客上宣布Canary版本中的任何重大破坏性更改。Canary版本最接近Meta内部运行的代码,因此您通常可以预期它们相对稳定。但是,您需要固定版本并在更新已固定提交之间的内容时手动扫描GitHub提交日志。
我们预计大多数在精选设置(如框架)之外使用React的人将希望继续使用稳定版本。但是,如果您正在构建框架,您可能需要考虑捆绑固定到特定提交的Canary版本的React,并按照您自己的节奏更新它。这样做的好处是,您可以为您的用户更早地发布单独完成的React功能和错误修复,并按照您自己的发布计划进行,这与React Native过去几年一直在做的事情类似。缺点是您需要承担额外的责任来审查正在引入哪些React提交,并向您的用户传达您的版本中包含哪些React更改。
如果您是框架作者并想尝试这种方法,请联系我们。
提前宣布破坏性更改和新功能
Canary版本代表我们对任何给定时间将包含到下一个稳定React版本中的内容的最佳猜测。
传统上,我们只在发布周期结束时(进行主要版本发布时)宣布破坏性更改。现在Canary版本已成为正式支持的React使用方式,我们计划转向在Canary版本中落地时宣布破坏性更改和重要的新功能。例如,如果我们合并了一个将包含在Canary版本中的破坏性更改,我们将在React博客上撰写一篇关于它的文章,如果需要,还包括代码修改和迁移说明。然后,如果您是框架作者,正在发布更新已固定的React Canary版本以包含该更改的主要版本,您可以从您的发行说明中链接到我们的博客文章。最后,当React的稳定主要版本准备就绪时,我们将链接到那些已经发布的博客文章,我们希望这将帮助我们的团队更快地取得进展。
我们计划在Canary版本中记录API——即使这些API在Canary版本之外尚不可用。仅在Canary版本中可用的API将在相应的页面上标有特殊说明。这将包括像 use
之类的API,以及其他一些API(例如 cache
和 createServerContext
),我们将为此发送RFC。
必须固定Canary版本
如果您决定为您的应用程序或框架采用Canary工作流程,请确保始终固定您正在使用的Canary的确切版本。由于Canary版本是预发布版本,它们可能仍然包含破坏性更改。
示例:React服务器组件
正如我们在三月份宣布的那样,React服务器组件约定已经最终确定,我们预计不会出现与其用户界面API契约相关的重大破坏性更改。但是,我们还不能在稳定的React版本中发布对React服务器组件的支持,因为我们仍在处理几个相互关联的仅限框架的功能(例如 资源加载),并预计在那里会有更多破坏性更改。
这意味着React服务器组件已准备好被框架采用。但是,在下一个主要React版本发布之前,框架采用它们的唯一方法是发布一个固定的Canary版本的React。(为了避免捆绑两个React副本,希望这样做 的框架需要强制解析 react
和 react-dom
到他们与他们的框架一起发布的固定的Canary版本,并向他们的用户解释这一点。例如,这就是Next.js App Router所做的。)
针对稳定版和Canary版本测试库
我们不希望库作者测试每个Canary版本,因为这将非常困难。但是,正如我们 三年前最初引入不同的React预发布渠道时一样,我们鼓励库针对最新的稳定版本和最新的Canary版本运行测试。如果您看到未宣布的行为变化,请在React存储库中提交错误,以便我们可以帮助诊断它。我们预计,随着这种实践的广泛采用,升级库到新的主要React版本所需的工作量将减少,因为意外的回归将在它们落地时被发现。
稳定版本的工作方式与之前相同
我们没有对稳定的 React 版本进行任何更改。