React Canary 版本:在 Meta 之外實現功能增量發佈

2023 年 5 月 3 日,由 Dan AbramovSophie AlpertRick HanlonSebastian MarkbågeAndrew Clark 發佈


我們希望讓 React 社群能夠在個別新功能設計接近完成後,就能立即採用,不必等到穩定版本發佈——類似於 Meta 長期以來在內部使用 React 最新版本的方式。我們正在推出一個新的官方支援的 Canary 發佈通道。它允許框架等精心策劃的設定將個別 React 功能的採用與 React 發佈時程分離。


簡而言之

  • 我們將推出官方支援的 React Canary 發佈通道。由於它受到官方支援,如果出現任何回歸,我們會以與穩定版本中的錯誤類似的緊急程度來處理它們。
  • Canary 版本可讓您在個別新 React 功能進入語義化版本控制的穩定版本之前開始使用它們。
  • 實驗性 通道不同,React Canary 版本僅包含我們合理認為已準備好採用的功能。我們鼓勵框架考慮綁定特定的 Canary React 版本。
  • 我們將在部落格上發佈 Canary 版本中發生的重大變更和新功能。
  • 一如既往,React 的每個穩定版本都遵循語義化版本控制。

React 功能通常是如何開發的

通常,每個 React 功能都會經歷相同的階段

  1. 我們會開發一個初始版本,並在其前面加上 `experimental_` 或 `unstable_` 前綴。該功能僅在 `experimental` 發佈通道中可用。此時,預計該功能將發生重大變化。
  2. 我們會在 Meta 中找到一個願意幫助我們測試此功能並提供回饋的團隊。這會導致一輪變更。隨著功能變得更加穩定,我們會與 Meta 中的更多團隊合作試用它。
  3. 最終,我們對設計充滿信心。我們從 API 名稱中移除前綴,並將該功能預設在 `main` 分支上提供,大多數 Meta 產品都使用此分支。此時,Meta 中的任何團隊都可以使用此功能。
  4. 隨著我們對方向建立信心,我們還會為新功能發佈 RFC。此時,我們知道該設計適用於廣泛的案例,但我們可能會在最後一刻進行一些調整。
  5. 當我們快要推出開源版本時,我們會為該功能撰寫文件,並最終在穩定的 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 功能在瀏覽器中發佈,然後才正式批准為規範的一部分一樣。

為何不使用實驗版本?

雖然技術上可以使用實驗版本 (Experimental releases),但我們不建議在正式環境中使用它們,因為實驗性 API 在穩定之前可能會經歷重大變更(甚至可能被完全移除)。雖然 Canary 版本也可能包含錯誤(就像任何版本一樣),但未來我們計劃在我們的部落格上宣布 Canary 版本中的任何重大變更。Canary 版本最接近 Meta 內部運行的程式碼,因此通常可以預期它們相對穩定。但是,您確實需要固定版本,並在固定版本之間更新時手動掃描 GitHub 的提交日誌。

我們預計大多數在非框架等策展環境下使用 React 的開發者會繼續使用穩定版本。 但是,如果您正在構建框架,您可能會考慮綁定特定版本的 Canary React 版本,並按照自己的步調更新它。這樣做的好處是,您可以更早地向您的使用者發布個別已完成的 React 功能和錯誤修復,並按照您自己的發布時程進行,類似於 React Native 過去幾年的做法。缺點是您需要承擔額外的責任,審查引入的 React 提交,並告知您的使用者您的版本中包含哪些 React 變更。

如果您是框架作者,並且想嘗試這種方法,請與我們聯繫。

提前宣布重大變更和新功能

Canary 版本代表了我們在任何給定時間點對下一個穩定 React 版本的最佳猜測。

傳統上,我們只在發布週期結束時(進行主要版本發布時)宣布重大變更。現在 Canary 版本是官方支援的 React 使用方式,我們計劃將重大變更和重要新功能的宣布提前到它們在 Canary 版本中發布時。例如,如果我們合併一個將在 Canary 版本中發布的重大變更,我們會在 React 部落格上撰寫一篇關於它的文章,必要時會包含程式碼修改工具和遷移說明。然後,如果您是框架作者,正在發布一個主要版本,將固定的 React Canary 版本更新為包含該變更,您可以從您的版本說明中連結到我們的部落格文章。最後,當 React 的穩定主要版本準備就緒時,我們將連結到那些已發布的部落格文章,我們希望這將有助於我們的團隊更快地取得進展。

我們計劃在 API 發布到 Canary 版本時就將其記錄下來,即使這些 API 在 Canary 版本之外尚無法使用。僅在 Canary 版本中可用的 API 將在相應頁面上以特殊註釋標記。這將包含像 use 等 API,以及我們將發布 RFC 的其他一些 API(例如 cachecreateServerContext)。

Canary 版本必須固定

如果您決定在您的應用程式或框架中採用 Canary 工作流程,請確保始終固定您正在使用的 Canary 版本的確切版本。由於 Canary 版本是預發布版本,因此它們可能仍然包含重大變更。

範例:React 伺服器元件

正如我們在三月宣布的,React 伺服器元件的規範已定稿,我們預計使用者端 API 方面不會有重大的變更。 然而,我們還不能在 React 的穩定版本中發布對 React 伺服器元件的支援,因為我們仍在開發幾個相互關聯的僅限框架的功能(例如 資源載入),並預計那裡會有更多重大變更。

這表示 React 伺服器元件已準備好被框架採用。 然而,在下一個 React 主要版本發布之前,框架採用它們的唯一方法是發布固定 Canary 版本的 React。(為了避免綁定兩個 React 副本,希望這樣做的框架需要強制將 reactreact-dom 解析為框架附帶的固定 Canary 版本,並向其使用者說明這一點。例如,這就是 Next.js App Router 的做法。)

針對穩定版本和 Canary 版本測試函式庫

我們不期望函式庫作者測試每個 Canary 版本,因為這將非常困難。 然而,就像我們在三年前最初引入不同的 React 預發布管道時一樣,我們鼓勵函式庫針對最新的穩定版本和最新的 Canary 版本運行測試。如果您看到未宣布的行為變更,請在 React 儲存庫中提交錯誤報告,以便我們幫助診斷。我們預計,隨著這種做法被廣泛採用,將減少將函式庫升級到 React 新主要版本所需的工作量,因為意外的回歸將在它們發布時被發現。

備註

嚴格來說,Canary 並不是一個新的發布管道 - 它以前被稱為 Next。 然而,我們決定將其重新命名,以避免與 Next.js 混淆。 我們將其宣布為一個*新*的發布管道,是為了傳達新的期望,例如 Canary 是官方支援的 React 使用方式。

穩定版本的操作方式與以往相同

我們沒有對穩定的 React 版本引入任何變更。