الانتقال إلى Biome في مشاريع بتقنيات مختلفة
الموضوعات: الأدوات · Biome · تجربة المطور
لو كان لدينا مستودع واحد حديث، لكان الانتقال من ESLint وPrettier إلى Biome تغييرًا قصيرًا. لكن المستودعات لم تبدأ في الوقت نفسه، ولا تستخدم الإصدار نفسه من React أو TypeScript، وبعض إعدادات lint فيها تحمل سنوات من القرارات الصغيرة.
بدأت بحصر الفحوصات الموجودة والأخطاء التي تكشفها، ثم قارنتها بما يتيحه Biome. بهذه الطريقة نعرف ما يمكن نقله مباشرة وما يحتاج إلى بديل.
السبب لم يكن السرعة وحدها
Biome أسرع، لكن السرعة لم تكن المشكلة الوحيدة. كنا نواجه يوميًا اختلافًا في نتائج الفحص: الكود نفسه ينجح في مستودع ويفشل في آخر. وكان كل تحديث لـ React أو TypeScript يتطلب التحقق مجددًا من توافق إضافات ESLint.
كنا نريد أوامر متشابهة في كل مستودع، وإعدادًا يمكن فهمه من دون تتبع سلسلة من ملفات extends، وأداة سريعة بما يكفي لتعمل محليًا قبل أن ينتظر المهندس CI.
لا يعني ذلك أن قواعد ESLint سيئة. بعض قواعده أعمق من Biome، وبعض الإضافات تحل مشاكل حقيقية. أردنا تقليل الأدوات والإعدادات التي نصونها، مع الاحتفاظ بالفحوصات التي تمنع الأخطاء المهمة.
استخرج الإعداد الفعلي أولًا
قبل لمس أول مستودع، أستخرج إعداد ESLint بعد دمج كل ملفات extends. القائمة النهائية غالبًا مختلفة عما يبدو في الملف الرئيسي.
أصنف القواعد إلى مجموعات أفهمها: أخطاء فعلية، وقواعد React، وإمكانية الوصول، والاستيرادات، والتنسيق، واتفاقات خاصة بالفريق. ثم أضع أمام كل قاعدة جوابًا واحدًا:
- لدى Biome بديل مباشر؛
- يتولاها TypeScript بصورة أفضل؛
- نحتاج إلى فحص مستقل لها؛
- لم تعد تخدمنا ويمكن حذفها.
هذه القائمة أهم من ملف biome.json. من دونها قد يبدو الترحيل ناجحًا لأن فحوصات CI نجحت، بينما اختفى فحص كان يمنع خطأ حقيقيًا.
افصل التنسيق عن lint
أبدأ بالتنسيق لأنه أقل خطورة. أضبط Biome، أشغّل biome format --write على المستودع، وأضع التغيير في commit مستقل لا يحمل أي تعديل يدوي.
{
"formatter": {
"enabled": true,
"indentStyle": "space"
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}قد يشمل هذا commit ملفات كثيرة، لكن محتواه يقتصر على التنسيق، ليسهل التأكد من أنه لم يغيّر سلوك الكود. أضيفه إلى .git-blame-ignore-revs حتى يستطيع الفريق تتبّع تعديلات الأسطر التي سبقت التنسيق، ثم أحذف إعداد Prettier القديم. لا أترك الأداتين تعملان معًا؛ اختلاف واحد بينهما يكفي لإضافة تغييرات شكلية متكررة إلى كل طلب دمج.
بعد استقرار التنسيق، أنتقل إلى lint. هنا تصبح التغييرات أصغر وأسهل للمراجعة: إصلاح قاعدة، أو استثناء محدود مع سبب، أو فحص يبقى مؤقتًا خارج Biome.
لا ترحّل كل المستودعات في يوم واحد
المستودعات الحديثة أسهل عادةً، لذلك أبدأ بواحد منها. يوضح هذا شكل الإعداد النهائي والأوامر التي سيستخدمها الفريق من دون أن نتعطّل منذ البداية بسبب إعدادات قديمة يصعب نقلها.
بعد نجاحه، يصبح لدينا نموذج نكرره. لكنني لا أنسخ الملف فقط؛ أراجع الفروق التي اكتشفتها في مرحلة الحصر. مستودع قديم قد يحتاج إلى إعداد مؤقت، وقد يكون من الأفضل تأجيله حتى يأتي عمل فعلي يبرر كلفة التغيير.
لا أرى مشكلة في أن يبقى مستودع واحد على ESLint فترة أطول إذا كان مستقرًا ولا يتغير. المشكلة هي أن ندعي اكتمال الترحيل بينما توجد أوامر مختلفة لا يعرفها الفريق.
بعد كل مستودع أسأل المهندس الذي لم يشارك في الترحيل أن يشغّل الأوامر بنفسه. إذا احتاج إلى شرح شفهي، فالإعداد لم يكتمل بعد. هذه التجربة الصغيرة تكشف أشياء لا تظهر على جهازي: إضافة محرر ما زالت تعمل، أو أمر قديم في README، أو مسار في CI لا يستخدم الإعداد الجديد أصلًا. الترحيل الجيد يجب أن يكون واضحًا لمن يفتح المستودع بعدنا، لا لمن كتب ملف الإعداد.
الأشياء التي تتعطل عادةً
أول شيء هو إعداد المحرر. تغيير ملف في المستودع أسهل من التأكد أن جميع أعضاء الفريق أوقفوا Prettier وفعّلوا Biome بالطريقة نفسها. لذلك أوثق إضافة المحرر وإعداد الحفظ، وأجعل CI المرجع النهائي إذا اختلفت البيئة المحلية.
الثاني هو الملفات المولّدة. إما أن نستثنيها كلها ونترك الأداة التي ولدتها مسؤولة عن تنسيقها، أو ننسقها بالسياسة نفسها. الحل المختلط يجعل كل تشغيل لـ codegen ينتج تغييرات لا علاقة لها بالميزة.
الثالث هو القواعد التي لا يملك Biome بديلًا لها. لا أخفيها داخل TODO عام. أسجل اسم القاعدة والمخاطرة التي كانت تغطيها، ثم أحدد إن كان TypeScript أو الاختبار أو المراجعة يكفي مؤقتًا.
اعتماد فحص موحّد في CI
إضافة المحرر تساعد، لكن الأمر الذي يمنع الدمج يجب أن يكون واحدًا في كل مكان. أثبت إصدار Biome، وأضيف أمرًا واضحًا للتشغيل المحلي، ثم أستخدم الأمر نفسه في CI:
{
"scripts": {
"check": "biome check .",
"check:ci": "biome ci ."
}
}الاستثناءات يجب أن تكون مرئية وقريبة من السطر الذي يحتاجها. إذا احتاج مجلد قديم إلى تجاوز أوسع، أضعه في الإعداد مع تعليق يشرح السبب. الاستثناء بلا سبب يتحول بسرعة إلى قاعدة دائمة.
وقبل الانتقال إلى المستودع التالي، أسجل أربع معلومات: إصدار Biome، وأمر الفحص، والاستثناءات الموجودة، والملفات الخارجة من النطاق. هذا السجل القصير يمنعنا من إعادة النقاش نفسه بعد أسبوع.
متى أعد الترحيل ناجحًا؟
ليس عندما نحذف آخر ملف ESLint. أعده ناجحًا عندما يستطيع المهندس الانتقال إلى مستودع آخر وتشغيل الأمر نفسه والحصول على النتيجة نفسها، وعندما تمنع الأداة الجديدة أخطاء جديدة بدل الاكتفاء بإعادة تنسيق الكود الموجود.
إلى جانب سرعة الفحص، أصبح الانتقال بين المستودعات أسهل. وفي بيئة تضم مشاريع كثيرة، يوفّر توحيد الأوامر والإعدادات وقتًا يتكرر توفيره مع كل مهمة.