سياسة الإصدارات في React

من موسوعة حسوب

تتبع React مبادئ الإدارة الدلالية لنُسخ البرمجيات (SemVer) في ترقيم إصداراتها.

هذا يعني أنَّه مع الإصدار ذي الرقم x.y.z:

  • عند إصدار تغييرات جذرية (breaking changes)، نطلق إصدارًا رئيسيًّا عبر تغيير الرقم x (مثل الانتقال من 15.6.2 إلى 16.0.0).
  • عند إصدار ميزات جديدة، نطلق إصدارًا فرعيًّا عبر تغيير الرقم y (مثل التغيير من 15.6.2 إلى 15.7.0).
  • عند تصحيح علل وثغرات في الإصدار السابق، نطلق إصدارًا مرقَّعًا (patch release) عبر تغيير الرقم z (مثل تغيير 15.6.2 إلى 15.6.3).

قد تحوي الإصدارات الرئيسية على ميزات جديدة أيضًا، ويمكن أي يحوي أي إصدار على تصحيح لعللٍ وثغرات. تعلم المزيد عن الإصدارات المُسبقة.

التغييرات الجذرية

نعلم أنَّ التغييرات الجذرية غير محبَّبة لجميع الأشخاص، لذا نحاول قدر الإمكان تقليل عدد الإصدارات الرئيسية. على سبيل المثال، الإصدار 15 من React نُشِر في نيسان عام 2016 والإصدار 16 نُشِر في أيلول من العام 2017. ولا يتوقع نشر الإصدار 17 حتى العام 2020.

عوض ذلك، ننشر إصدارات فرعية تحوي الميزات الجديدة. هذا يعني أنَّ الإصدارات الفرعية هي التي تجذب الانتباه أكثر من الإصدارات الرئيسية على خلاف ما قد توحي تسميتها.

الالتزام بالاستقرار

لمَّا كنا نعدِّل على React باستمرار، نحاول قدر المستطاع تقليل الجهد المطلوب للاستفادة من الميزات الجديدة. سنبقي الواجهات البرمجية القديمة قيد العمل عندما يكون ذلك ممكنًا حتى لو تطلَّب الأمر وضعها في حزمة منفصلة. على سبيل المثال، ثُبِّطت المخاليط من سنوات خلت إلا أنَّها لا تزال مدعومةً إلى هذه اللحظة عبر create-react-class، ولا تزال العديد من الشيفرات الأساسية (codebases) تستعملها في الشيفرة المستقرة والقديمة.

يستعمل React اليوم أكثر من مليون مطور؛ يعمل هؤلاء المطورين على صيانة ملايين المكونات. تحتوي الشيفرة الأساسية لفيسبوك مثلًا على أكثر من 50,000 مكون من مكونات React. هذا يعني أنَّه نحتاج إلى جعل عملية الترقية إلى إصدارات React الحديثة عمليةً سهلةً قدر الإمكان. إن أحدثنا تغييرات كبيرة دون توفير مسارٍ ينقلنا بسلاسةٍ إليها، فسيبقى الجميع عالقًا في الإصدارات القديمة. نختبر مسارات الانتقال إلى الإصدارات الأحدث على فيسبوك بحد ذاته أولًا؛ فإن استطاع عشرة أفراد من فريقنا (وأقل) تحديث ما يزيد عن 50,000 مكون بمفردهم، نتأكد آنذاك من كون عملية الترقية قابلة للتطبيق والإدارة لأي شخص يستعمل React. نكتب في أغلب الحالات شيفرة مؤتمتة لتحديث صياغة المكونات ثم ننشرها في إصدار مفتوح المصدر ليستعملها الجميع.

الترقية التدريجية مقابل التحذيرات

تتضمن الإصدارات التطويرية من React الكثير من التحذيرات المفيدة. نضيف تحذيرات للتحضير للتغييرات الجذرية المستقبلية متى ما أمكن ذلك. بهذه الطريقة، إن لم يُظهِر تطبيقك أية تحذيرات مع أحدث إصدار، فسيكون متوافقًا مع الإصدار الرئيسي المقبل. يتيح لك هذا أن تحدث تطبيقك مكونة بعد مكونة.

لن تؤثر التحذيرات في الإصدارات التطويرية على سلوك تطبيقك في وقت التشغيل. بناءً على ذلك، يمكنك الوثوق من عمل تطبيقك في البيئة التطويرية والبيئة الإنتاجية دون أي اختلاف. الفرق الوحيد هو أنه لن تُسجَّل التحذيرات في البيئة الإنتاجية مما يزيد من فعالية تطبيقك. (إن لاحظت أي سلوك مخالف لما ذكرناه، أرجو أن تخبرنا به في أسرع وقت.)

ما هي التغييرات التي تعدُّ جذرية؟

عمومًا، لا نغيِّر رقم الإصدار الرئيسي (الرقم x) فجأةً من أجل التغييرات التالية:

  • التحذيرات في البيئة التطويرية: لمَّا كانت هذه التحذيرات لا تؤثر على البيئة الإنتاجية، فقد نضيف تحذيرات أو نعدِّل على أخرى موجودة مسبقًا بين الإصدارات الرئيسية. هذا ما يسمح لنا في الحقيقة بالتحذير بشكل موثوق بقدوم تغييرات جذرية مستقبلية.
  • تبدأ الواجهات البرمجية مع الإصدارات غير المستقرة: تضاف الواجهات البرمجية الجديدة في الإصدارات غير المستقرة على أنَّها ميزات تجريبية، إذ لم نكن قد تأكدنا بعد منها. بعد إصدار مثل هذه الواجهات البرمجية في إصدارات تحوي السابقة unstable_‎، يمكننا نقلها بسرعة إلى الإصدار المستقر والحصول على الواجهة البرمجية المستقرة.
  • الإصداران Alpha و Canary من React: نوفر الإصدارات Alpha من React من أجل اختبار الميزات الجديدة في وقت مبكر، إذ نريد مرونةً أكبر تسمح لنا بجعل التغييرات تعتمد على ما تعلمناه في هذه الإصدارات. إن كنت تستعمل أحد هذه الإصدارات، فانتبه إلى تغيِّر الواجهات البرمجية قبل نشرها في الإصدار المستقر.
  • الواجهات البرمجية غير الموثَّقة وهيكلية البيانات الداخلية: إن وصلت إلى أسماء خاصيات داخلية مثل ‎__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED أو ‎__reactInternalInstance$uk43rzhitjg، فذلك لأنها متاحةٌ لك، إذ لك حرية التصرف والوصول.

صُمِّمَت هذه السياسة لتكون واقعية وعملية في الوقت نفسه؛ فلا نريد بالتأكيد أن نُسبِّب لك المزيد من الصداع. إن أطلقنا إصدارًا رئيسيًّا لكل تغيير من التغييرات السابقة فجأةً، فسينتهي بنا المطاف بإطلاق إصدارات رئيسية لا تحصى وإصابة المجتمع بداءٍ سقيمٍ يدعى "رهاب الإصدارات". أضف إلى ذلك أنَّه لن نتمكن آنذاك من تطوير React بالشكل التي نسير عليه الآن.

أخيرًا، إن كان ولابد من إطلاق إصدار ناتج عن تغيير في تلك القائمة وقد يتسبَّب في وقوع المستخدمين في مشاكل كثيرة، فسنبذل قصارى جهدنا لتوفير وسيلة تسمح بالانتقال التدريجي إليه.

إذا لم يحتو الإصدار الثانوي على أي ميزات جديدة، فلماذا يُعد إصدارا مرقٍّعا؟

من المحتمل ألا تتضمن الإصدارات الفرعية أي ميزات جديدة. هذا مسموح به في مبادئ الإدارة الدلالية لنُسخ البرمجيات (SemVer)، والتي تنص على أنّه "يمكن زيادة [إصدار فرعي] في حال تم إدخال تحسينات أو وظائف جديدة جوهرية داخل الكود البرمجي الخاص. وقد تتضمن تغييرات ترقيعية."

يطرح هذا سؤالا: لماذا لا تُصنّف هذه الإصدارات إذن على أنها ترقيعات (patch) بدلاً من ذلك.

الإجابة هي أن أيّ تغيير في React (أو أي برنامج آخر) ينطوي على مخاطر إحداث كسور غير متوقعة. مثلا قد يؤدي إصدار ترقيع جديد يحل خللا ما إلى التسبب في حدوث خلل آخر غير متوقع. لن يكون هذا مزعجًا للمطورين فحسب، بل سيقلل ثقتهم في إصدارات الترقيع المستقبلية. وهذا أمر مؤسف خاصة إن كان الترقيع الأصلي يستهدف إصلاح خلل نادر الحدوث عمليا.

لدينا سجل حافل في تجنب الأخطاء في إصدارات React، بيد أنّ الجميع ينتظر أن تكون إصدارات الترقيع موثوقة، لأن معظم المطورين يفترضون أنه يمكن اعتمادها دون عواقب وخيمة.

لهذه الأسباب، نخصص إصدارات الترقيع لإصلاح أهم الأخطاء والثغرات الأمنية وحسب.

إذا اشتمل الإصدار على تغييرات غير أساسية - مثل معامِلات إعادة البناء الداخلية، أو تغييرات في تفاصيل التنفيذ، أو تحسينات في الأداء، أو إصلاح أخطاء طفيفة - فسنرفع رقم الإصدار الفرعي حتى في حالة عدم وجود ميزات جديدة.

انظر أيضًا

مصادر