React Canaries: מאפשרים השקה הדרגתית של יכולות מחוץ ל-Meta
3 במאי 2023 מאת Dan Abramov, Sophie Alpert, Rick Hanlon, Sebastian Markbåge, and Andrew Clark
אנחנו רוצים להציע לקהילת React אפשרות לאמץ יכולות חדשות בודדות ברגע שהעיצוב שלהן כמעט סופי, עוד לפני שהן משוחררות בגרסה יציבה, בדומה לאופן שבו Meta משתמשת במשך שנים בגרסאות bleeding-edge של React פנימית. אנחנו מציגים ערוץ שחרור חדש ונתמך רשמית: Canary release channel. הוא מאפשר ל-setups מנוהלים כמו frameworks לנתק בין אימוץ יכולות React ספציפיות לבין לוח הזמנים של שחרורי React.
tl;dr
- אנחנו מציגים ערוץ Canary release channel נתמך רשמית עבור React. בגלל שהוא נתמך רשמית, אם תיכנס רגרסיה נתייחס אליה בדחיפות דומה לבאגים בשחרורים יציבים.
- Canaries מאפשרים להתחיל להשתמש ביכולות חדשות ספציפיות של React לפני שהן נכנסות לשחרורי semver יציבים.
- בניגוד לערוץ Experimental, React Canaries כוללים רק יכולות שאנחנו מאמינים באופן סביר שהן מוכנות לאימוץ. אנחנו מעודדים frameworks לשקול שילוב של גרסאות Canary נעולות של React.
- נכריז בבלוג על שינויים שוברים ועל יכולות חדשות כשהם נכנסים לשחרורי Canary.
- כמו תמיד, React ממשיך לעקוב אחרי semver בכל שחרור יציב.
איך בדרך כלל מפותחות יכולות React
בדרך כלל כל יכולת ב-React עברה את אותם שלבים:
- אנחנו מפתחים גרסה ראשונית ומוסיפים לה קידומת
experimental_אוunstable_. היכולת זמינה רק בערוץ השחרורexperimental. בשלב הזה מצופה שהיא תשתנה משמעותית. - אנחנו מוצאים צוות ב-Meta שמוכן לעזור לבדוק את היכולת ולתת משוב. זה מוביל לסבב שינויים. כשהיכולת נעשית יציבה יותר, אנחנו עובדים עם צוותים נוספים ב-Meta שמנסים אותה.
- בסוף אנחנו מרגישים בטוחים בעיצוב. אנחנו מסירים את הקידומת משם ה-API, והיכולת זמינה כברירת מחדל בענף
main, שבו רוב מוצרי Meta משתמשים. בשלב הזה כל צוות ב-Meta יכול להשתמש בה. - ככל שהביטחון בכיוון גדל, אנחנו גם מפרסמים RFC עבור היכולת החדשה. בשלב הזה אנחנו יודעים שהעיצוב עובד על טווח רחב של מקרים, אבל ייתכנו התאמות של הרגע האחרון.
- כשאנחנו קרובים לשחרור קוד פתוח, אנחנו כותבים תיעוד ליכולת ולבסוף משחררים אותה בגרסה יציבה של React.
ה-playbook הזה עובד טוב לרוב היכולות ששחררנו עד היום. עם זאת, יכול להיות פער משמעותי בין הזמן שבו היכולת מוכנה לשימוש באופן כללי (שלב 3) לבין הזמן שבו היא משוחררת בקוד פתוח (שלב 5).
אנחנו רוצים להציע לקהילת React אפשרות ללכת בגישה דומה לזו של Meta, ולאמץ יכולות חדשות בודדות מוקדם יותר (ברגע שהן זמינות), בלי להמתין למחזור השחרור הבא של React.
כמו תמיד, כל יכולות React יגיעו בסוף לשחרור Stable.
למה לא פשוט להוציא יותר שחרורי minor?
באופן כללי, אנחנו כן משתמשים בשחרורי minor כדי להציג יכולות חדשות.
אבל זה לא תמיד אפשרי. לפעמים יכולות חדשות מקושרות ליכולות חדשות אחרות שעדיין לא הושלמו ואנחנו עדיין עושים עליהן איטרציה. אי אפשר לשחרר אותן בנפרד כי המימושים קשורים זה בזה. אי אפשר לגרס אותן בנפרד כי הן משפיעות על אותן חבילות (למשל react ו-react-dom). ואנחנו צריכים לשמר את היכולת להמשיך איטרציה על החלקים שלא מוכנים בלי סבב של גרסאות major מרובות, ש-semver היה מחייב.
ב-Meta פתרנו את זה על ידי בניית React מענף main, ועדכון ידני לקומיט נעול ספציפי בכל שבוע. זו גם הגישה שבה React Native עובד כבר כמה שנים. כל שחרור יציב של React Native נעול לקומיט ספציפי מענף main של מאגר React. זה מאפשר ל-React Native לכלול תיקוני באגים חשובים ולאמץ יכולות חדשות של React בהדרגה ברמת ה-framework, בלי להיות תלוי בלוח השחרורים הגלובלי של React.
אנחנו רוצים להפוך את זרימת העבודה הזו לזמינה גם ל-frameworks ול-setups מנוהלים אחרים. לדוגמה, זה מאפשר ל-framework שמעל React לכלול שינוי שובר שקשור ל-React לפני שהשינוי הזה נכנס לשחרור יציב של React. זה שימושי במיוחד כי חלק מהשינויים השוברים משפיעים רק על אינטגרציות framework. כך framework יכול לשחרר שינוי כזה בגרסת minor משלו בלי לשבור semver.
שחרורים מתגלגלים דרך ערוץ Canaries יתנו לנו לולאת משוב הדוקה יותר ויבטיחו שהיכולות החדשות מקבלות בדיקות מקיפות בקהילה. זרימת העבודה הזו קרובה יותר לאופן שבו TC39, ועדת התקנים של JavaScript, מטפלת בשינויים בשלבים ממוספרים. יכולות חדשות של React עשויות להיות זמינות ב-frameworks מבוססי React לפני שהן נכנסות לשחרור יציב של React, כמו שיכולות JavaScript חדשות מגיעות לדפדפנים לפני שהן מאושרות רשמית כחלק מהמפרט.
למה לא להשתמש בשחרורי experimental במקום?
למרות שמבחינה טכנית אפשר להשתמש ב-Experimental releases, אנחנו לא ממליצים להשתמש בהן בפרודקשן, כי APIs ניסיוניים יכולים לעבור שינויים שוברים משמעותיים בדרך לייצוב (או להימחק לגמרי). גם Canaries יכולים להכיל טעויות (כמו כל שחרור), אבל מעכשיו אנחנו מתכוונים להכריז בבלוג על שינויים שוברים משמעותיים ב-Canaries. Canaries הם הקרובים ביותר לקוד ש-Meta מריצה בפנים, ולכן בדרך כלל אפשר לצפות שיהיו יציבים יחסית. אבל כן צריך לנעול גרסה ולעבור ידנית על commit log ב-GitHub כשמעדכנים בין קומיטים נעולים.
אנחנו מצפים שרוב מי שמשתמש ב-React מחוץ ל-setup מנוהל (כמו framework) ימשיך להשתמש בשחרורי Stable. אבל אם אתם בונים framework, כדאי לשקול שילוב גרסת Canary של React שנעולה לקומיט מסוים ולעדכן בקצב שלכם. היתרון הוא שזה מאפשר לשחרר למשתמשים שלכם יכולות ותיקוני באגים בודדים של React מוקדם יותר ובקצב השחרור שלכם, בדומה למה ש-React Native עושה כבר כמה שנים. החיסרון הוא שאתם לוקחים אחריות נוספת לבדוק אילו קומיטים של React נכנסים ולעדכן את המשתמשים אילו שינויים ב-React נכללים בכל שחרור שלכם.
אם אתם מחברי framework ורוצים לנסות את הגישה הזו, דברו איתנו.
הכרזה מוקדמת על שינויים שוברים ויכולות חדשות
שחרורי Canary מייצגים את ההערכה הטובה ביותר שלנו בכל רגע למה ייכנס לשחרור היציב הבא של React.
באופן מסורתי הכרזנו על שינויים שוברים רק בסוף מחזור השחרור (בזמן major release). עכשיו כש-Canary הוא דרך נתמכת רשמית לצרוך React, אנחנו מתכננים לעבור להכריז על שינויים שוברים ועל יכולות חדשות משמעותיות ברגע שהם נכנסים ל-Canaries. לדוגמה, אם נמזג שינוי שובר שייצא ב-Canary, נכתוב עליו פוסט בבלוג React כולל codemods והנחיות מיגרציה לפי הצורך. לאחר מכן, אם אתם מחברי framework שמוציאים major release ומעדכנים את React canary הנעול כדי לכלול את השינוי הזה, תוכלו לקשר לפוסט שלנו מתוך release notes. ולבסוף, כשגרסת major יציבה של React תהיה מוכנה, נקשר לאותם פוסטים שכבר פורסמו, מה שלדעתנו יעזור לצוות להתקדם מהר יותר.
אנחנו מתכננים לתעד APIs ברגע שהם נכנסים ל-Canaries, גם אם הם עדיין לא זמינים מחוץ לערוץ הזה. APIs שזמינים רק ב-Canaries יסומנו עם הערה מיוחדת בדפים המתאימים. זה יכלול APIs כמו use, ועוד כמה נוספים (כמו cache ו-createServerContext) שעבורם נפרסם RFCs.
חייבים לנעול Canaries
אם החלטתם לאמץ את זרימת העבודה של Canary באפליקציה או ב-framework שלכם, ודאו שאתם תמיד נועלים את הגרסה המדויקת של Canary שאתם משתמשים בה. מכיוון ש-Canaries הם prereleases, הם עדיין יכולים לכלול שינויים שוברים.
דוגמה: React Server Components
כפי שהכרזנו במרץ, הקונבנציות של React Server Components נסגרו, ואנחנו לא מצפים לשינויים שוברים משמעותיים בחוזה ה-API שנראה למשתמש. עם זאת, עדיין אי אפשר לשחרר תמיכה ב-React Server Components בגרסה יציבה של React כי אנחנו ממשיכים לעבוד על כמה יכולות שקשורות ל-framework בלבד (כמו asset loading) ומצפים לעוד שינויים שוברים שם.
המשמעות היא ש-React Server Components כבר מוכנים לאימוץ על ידי frameworks. אבל עד שחרור major הבא של React, הדרך היחידה ל-framework לאמץ אותם היא לשחרר גרסת Canary נעולה של React. (כדי להימנע מבאנדל של שני עותקי React, frameworks שבוחרים בכך צריכים לאכוף resolution של react ו-react-dom לגרסת ה-Canary הנעולה שהם משחררים עם ה-framework, ולהסביר זאת למשתמשים שלהם. לדוגמה, כך עובד Next.js App Router.)
בדיקת ספריות מול גרסאות Stable וגם Canary
אנחנו לא מצפים ממחברי ספריות לבדוק כל שחרור Canary בודד, כי זה קשה מדי. אבל כמו שעודדנו כש-הצגנו במקור את ערוצי ה-prerelease השונים של React לפני שלוש שנים, אנחנו מעודדים ספריות להריץ בדיקות מול גם גרסת Stable האחרונה וגם גרסת Canary האחרונה. אם אתם רואים שינוי התנהגות שלא הוכרז, פתחו באג במאגר React כדי שנוכל לעזור לאבחן. אנחנו מצפים שככל שהפרקטיקה הזו תהפוך לנפוצה, היא תפחית את המאמץ שנדרש לשדרג ספריות לגרסאות major חדשות של React, כי רגרסיות אקראיות יימצאו מוקדם.
שחרורים יציבים עובדים כמו קודם
אנחנו לא משנים שום דבר באופן שבו שחרורי React יציבים עובדים.