מדיניות גרסאות
כל הגרסאות היציבות של React עוברות רמת בדיקות גבוהה ופועלות לפי ניהול גרסאות סמנטי (semver). React מציעה גם ערוצי הפצה לא יציבים כדי לעודד משוב מוקדם על יכולות ניסיוניות. הדף הזה מסביר למה אפשר לצפות משחרורי React.
שחרורים יציבים
שחרורי React יציבים (מוכרים גם כערוץ “Latest”) פועלים לפי עקרונות semantic versioning (semver).
כלומר, במספר גרסה x.y.z:
- כשמשחררים תיקוני באגים קריטיים, מבצעים patch release על ידי שינוי המספר z (לדוגמה: 15.6.2 ל-15.6.3).
- כשמשחררים יכולות חדשות או תיקונים לא קריטיים, מבצעים minor release על ידי שינוי המספר y (לדוגמה: 15.6.2 ל-15.7.0).
- כשמשחררים שינויים שוברים, מבצעים major release על ידי שינוי המספר x (לדוגמה: 15.6.2 ל-16.0.0).
שחרורי major יכולים לכלול גם יכולות חדשות, וכל שחרור יכול לכלול תיקוני באגים.
שחרורי minor הם סוג השחרור הנפוץ ביותר.
שינויים שוברים
שינויים שוברים לא נוחים לכולם, לכן אנחנו מנסים לצמצם את מספר שחרורי ה-major. לדוגמה, React 15 שוחרר באפריל 2016, React 16 בספטמבר 2017, ו-React 17 באוקטובר 2020.
במקום זאת, אנחנו משחררים יכולות חדשות בגרסאות minor. לכן שחרורי minor לעיתים קרובות מעניינים ומשמעותיים יותר מ-major, למרות השם הצנוע שלהם.
מחויבות ליציבות
כשאנחנו משנים את React לאורך זמן, אנחנו מנסים לצמצם את המאמץ שנדרש כדי ליהנות מיכולות חדשות. כשאפשר, נשמור על API ישן עובד גם אם זה אומר להעביר אותו לחבילה נפרדת. לדוגמה, לא ממליצים על mixins כבר שנים, אבל עדיין יש להם תמיכה באמצעות create-react-class, ובסיסי קוד רבים ממשיכים להשתמש בהם בקוד לגאסי יציב.
יותר ממיליון מפתחים משתמשים ב-React, וביחד מתחזקים מיליוני קומפוננטות. בבסיס הקוד של Facebook לבדו יש יותר מ-50,000 קומפוננטות React. לכן אנחנו צריכים להפוך את השדרוג לגרסאות חדשות לקל ככל האפשר. אם נעשה שינויים גדולים בלי נתיב מיגרציה, אנשים ייתקעו על גרסאות ישנות. אנחנו בודקים את נתיבי השדרוג האלה גם ב-Facebook עצמה. אם צוות של פחות מ-10 אנשים יכול לעדכן לבד יותר מ-50,000 קומפוננטות, אנחנו מקווים שגם לאחרים יהיה אפשר לנהל את השדרוג. בהרבה מקרים אנחנו כותבים סקריפטים אוטומטיים לשדרוג תחביר קומפוננטות, ואז מפרסמים אותם בקוד פתוח כדי שכולם יוכלו להשתמש.
שדרוגים הדרגתיים דרך אזהרות
גרסאות הפיתוח של React כוללות הרבה אזהרות מועילות. כשאפשר, אנחנו מוסיפים אזהרות כהכנה לשינויים שוברים עתידיים. כך, אם לאפליקציה שלך אין אזהרות בגרסה האחרונה, היא תהיה תואמת גם לגרסת ה-major הבאה. זה מאפשר לשדרג אפליקציות קומפוננטה אחרי קומפוננטה.
אזהרות פיתוח לא משפיעות על התנהגות זמן הריצה של האפליקציה. לכן אפשר להיות בטוחים שהאפליקציה תתנהג אותו הדבר בין build פיתוח ל-build ייצור. ההבדלים היחידים הם שבייצור לא יופיעו אזהרות, וה-build יעיל יותר. (אם ראית משהו אחר, פתחו issue.)
מה נחשב לשינוי שובר?
בדרך כלל אנחנו לא מעלים מספר major עבור שינויים ב:
- אזהרות פיתוח. מכיוון שהן לא משפיעות על ייצור, אנחנו יכולים להוסיף אזהרות חדשות או לשנות אזהרות קיימות בין גרסאות major. למעשה, זה מה שמאפשר לנו להתריע בצורה אמינה על שינויים שוברים עתידיים.
- APIs שמתחילים ב-
unstable_. אלה יכולות ניסיוניות שעדיין אין לנו ביטחון מלא ב-API שלהן. שחרור עם הקידומתunstable_מאפשר לנו להתקדם מהר יותר ולהגיע מוקדם יותר ל-API יציב. - גרסאות Alpha ו-Canary של React. אנחנו מספקים גרסאות alpha כדי לבדוק יכולות חדשות מוקדם, אבל צריכים גמישות לבצע שינויים לפי מה שנלמד בתקופת ה-alpha. אם משתמשים בגרסאות האלה, חשוב לדעת ש-APIs יכולים להשתנות לפני שחרור יציב.
- APIs לא מתועדים ומבני נתונים פנימיים. אם ניגשים לשמות פנימיים כמו
__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIREDאו__reactInternalInstance$uk43rzhitjg, אין שום הבטחה. אתם לבד.
המדיניות הזו פרגמטית: אנחנו לא רוצים לייצר לכם כאב ראש. אם היינו מעלים major על כל השינויים האלה, היינו מוציאים הרבה יותר גרסאות major ובסוף גורמים ליותר כאב סביב ניהול גרסאות בקהילה. זה גם היה מאט אותנו בשיפור React.
עם זאת, אם אנחנו מצפים ששינוי מרשימה זו יגרום בעיות רחבות בקהילה, עדיין נעשה כמיטב יכולתנו לספק נתיב מיגרציה הדרגתי.
אם בגרסת minor אין יכולות חדשות, למה זו לא גרסת patch?
ייתכן שגרסת minor לא תכלול יכולות חדשות. semver מאפשר זאת, וקובע ש-”[minor version] MAY be incremented if substantial new functionality or improvements are introduced within the private code. It MAY include patch level changes.”
ובכל זאת עולה השאלה למה לא לגרס את השחרורים האלה כ-patch.
התשובה היא שכל שינוי ב-React (או בכל תוכנה אחרת) נושא סיכון לשבירה לא צפויה. דמיינו מצב שבו patch שמתקן באג אחד מכניס בטעות באג אחר. זה לא רק מפריע למפתחים, אלא גם פוגע באמון בגרסאות patch עתידיות. זה מצער במיוחד כשהתיקון המקורי נועד לבאג שכמעט לא פוגשים בפועל.
יש לנו היסטוריה טובה של שחרורי React נקיים מבאגים, אבל לגרסאות patch יש רף אמינות אפילו גבוה יותר כי רוב המפתחים מניחים שאפשר לאמץ אותן ללא השלכות שליליות.
לכן אנחנו שומרים שחרורי patch רק לבאגים הקריטיים ביותר ולפגיעויות אבטחה.
אם שחרור כולל שינויים לא חיוניים, למשל ריפקטור פנימי, שינויים בפרטי מימוש, שיפורי ביצועים או תיקוני באגים קטנים, נעלה את גרסת ה-minor גם אם אין יכולות חדשות.
כל ערוצי ההפצה
React נשענת על קהילת קוד פתוח פעילה שמדווחת באגים, פותחת pull requests ו-מגישה RFCs. כדי לעודד משוב אנחנו לפעמים משתפים גרסאות מיוחדות של React שכוללות יכולות שעדיין לא שוחררו.
כל ערוץ הפצה של React מיועד לשימוש שונה:
- Latest מיועד לגרסאות React יציבות לפי semver. זה מה שמקבלים כשמתקינים React מ-npm. זה הערוץ שבו אתם כבר משתמשים היום. אפליקציות למשתמשי קצה שצורכות React ישירות משתמשות בערוץ הזה.
- Canary עוקב אחרי הענף הראשי של מאגר הקוד של React. אפשר לחשוב עליו כעל release candidates לגרסת ה-semver הבאה. Frameworks או setups מנוהלים אחרים יכולים לבחור בערוץ הזה עם גרסה נעולה של React. אפשר גם להשתמש ב-Canary לבדיקות אינטגרציה בין React לפרויקטי צד שלישי.
- Experimental כולל APIs ויכולות ניסיוניות שלא זמינות בגרסאות יציבות. גם הערוץ הזה עוקב אחרי הענף הראשי, אבל עם דגלי יכולות נוספים מופעלים. משתמשים בו כדי לנסות יכולות עתידיות לפני שחרור.
כל הגרסאות מתפרסמות ל-npm, אבל רק Latest משתמש ב-semantic versioning. גרסאות prerelease (בערוצי Canary ו-Experimental) מקבלות מספר גרסה שנוצר מ-hash של התוכן ותאריך הקומיט, למשל 18.3.0-canary-388686f29-20230503 עבור Canary ו-0.0.0-experimental-388686f29-20230503 עבור Experimental.
גם Latest וגם Canary נתמכים רשמית לאפליקציות למשתמשי קצה, אבל עם ציפיות שונות:
- גרסאות Latest פועלות לפי מודל semver המסורתי.
- גרסאות Canary חייבות להיות נעולות לגרסה ועלולות לכלול שינויים שוברים. הן מיועדות ל-setup מנוהל (כמו frameworks) שרוצה לשחרר יכולות חדשות ותיקוני באגים של React בקצב שחרור משלו.
גרסאות Experimental ניתנות לצורכי בדיקה בלבד, ואין לנו הבטחה שההתנהגות לא תשתנה בין שחרורים. הן לא פועלות לפי semver כמו הערוץ Latest.
פרסום גרסאות prerelease לאותו רג’יסטרי שבו אנחנו משתמשים לגרסאות יציבות מאפשר לנו להיעזר בכלים שתומכים בזרימת העבודה של npm, כמו unpkg ו-CodeSandbox.
ערוץ Latest
Latest הוא הערוץ של גרסאות React יציבות. הוא תואם לתגית latest ב-npm. זה הערוץ המומלץ לכל אפליקציות React שמופצות למשתמשים אמיתיים.
אם לא בטוחים באיזה ערוץ לבחור, בוחרים Latest. אם אתם משתמשים ב-React ישירות, זה כנראה מה שאתם כבר עושים. אפשר לצפות לעדכונים יציבים מאוד בערוץ הזה. המספור פועל לפי semver, כפי ש-תואר קודם.
ערוץ Canary
ערוץ Canary הוא ערוץ prerelease שעוקב אחרי הענף הראשי של מאגר React. אנחנו משתמשים בשחרורי Canary כ-release candidates לערוץ Latest. אפשר לראות ב-Canary superset של Latest שמתעדכן בתדירות גבוהה יותר.
רמת השינוי בין שחרור Canary האחרון לשחרור Latest האחרון דומה בקירוב למה שרואים בין שתי גרסאות minor ב-semver. עם זאת, ערוץ Canary לא עומד ב-semantic versioning. יש לצפות לשינויים שוברים מדי פעם בין שחרורים עוקבים בערוץ הזה.
אל תשתמשו ב-prerelease ישירות באפליקציות למשתמשי קצה אלא אם אתם פועלים לפי תהליך Canary.
שחרורי Canary מתפרסמים עם התגית canary ב-npm. הגרסאות נוצרות מ-hash של תוכן הבנייה ותאריך הקומיט, למשל 18.3.0-canary-388686f29-20230503.
שימוש בערוץ canary לבדיקות אינטגרציה
ערוץ Canary תומך גם בבדיקות אינטגרציה בין React לפרויקטים אחרים.
כל שינוי ב-React עובר בדיקות פנימיות נרחבות לפני שהוא מגיע לציבור. אבל באקו-סיסטם של React יש אינספור סביבות וקונפיגורציות, ואי אפשר לבדוק כולן.
אם אתם מחברי framework, ספרייה, כלי פיתוח או פרויקט תשתיתי דומה עבור React, תוכלו לעזור לנו לשמור על יציבות React למשתמשים שלכם ולכל הקהילה על ידי הרצה תקופתית של חבילת הבדיקות מול השינויים האחרונים. אם זה רלוונטי עבורכם, פעלו כך:
-
הגדירו cron job בפלטפורמת ה-CI המועדפת עליכם. גם CircleCI וגם Travis CI תומכות בכך.
-
בתוך ה-cron job עדכנו את חבילות React לגרסה האחרונה בערוץ Canary באמצעות התגית
canaryב-npm. עם npm cli:npm update react@canary react-dom@canaryאו עם yarn:
yarn upgrade react@canary react-dom@canary -
הריצו את חבילת הבדיקות שלכם מול החבילות המעודכנות.
-
אם הכול עובר, מצוין. סביר שהפרויקט שלכם יעבוד גם עם גרסת ה-minor הבאה של React.
-
אם משהו נשבר בצורה לא צפויה, עדכנו אותנו על ידי פתיחת issue.
פרויקט שמשתמש בתהליך הזה הוא Next.js. אפשר לראות את קונפיגורציית CircleCI שלהם כדוגמה.
ערוץ Experimental
כמו Canary, גם Experimental הוא ערוץ prerelease שעוקב אחרי הענף הראשי של מאגר React. בשונה מ-Canary, שחרורי Experimental כוללים יכולות ו-APIs נוספים שעדיין לא מוכנים לשחרור רחב.
בדרך כלל, עדכון ל-Canary ילווה בעדכון מקביל ל-Experimental. שניהם מבוססים על אותו source revision, אבל נבנים עם סט דגלי יכולות שונה.
שחרורי Experimental יכולים להיות שונים משמעותית מ-Canary ומ-Latest. אל תשתמשו בשחרורי Experimental באפליקציות למשתמשי קצה. יש לצפות לשינויים שוברים תכופים בין שחרורים בערוץ הזה.
שחרורי Experimental מתפרסמים עם התגית experimental ב-npm. הגרסאות נוצרות מ-hash של תוכן הבנייה ותאריך הקומיט, למשל 0.0.0-experimental-68053d940-20210623.
מה נכנס לשחרור experimental?
יכולות ניסיוניות הן יכולות שעדיין לא מוכנות לשחרור רחב, ועלולות להשתנות בצורה דרמטית לפני שהן נסגרות סופית. חלק מהניסויים לעולם לא יבשילו. הסיבה לקיומם היא בדיקת ההיתכנות של שינויים מוצעים.
למשל, אם ערוץ Experimental היה קיים כשפרסמנו את Hooks, היינו משחררים את Hooks לערוץ Experimental שבועות לפני שהיו זמינים ב-Latest.
ייתכן שיהיה לכם ערך בהרצת בדיקות אינטגרציה מול Experimental. זו החלטה שלכם. עם זאת, חשוב להבין ש-Experimental יציב אפילו פחות מ-Canary. אנחנו לא מבטיחים יציבות בין שחרורי Experimental.
איך אפשר ללמוד עוד על יכולות ניסיוניות?
יכולות ניסיוניות עשויות להיות מתועדות או שלא. בדרך כלל אנחנו לא מתעדים ניסויים עד שהם קרובים לשחרור ב-Canary או ב-Latest.
אם יכולת אינה מתועדת, ייתכן שיש לה RFC.
נפרסם ב-בלוג React כשנהיה מוכנים להכריז על ניסויים חדשים, אבל זה לא אומר שנפרסם כל ניסוי.
תמיד אפשר לעקוב אחרי ההיסטוריה במאגר GitHub הציבורי שלנו כדי לקבל רשימה מלאה של שינויים.