Oxlint: فحص الأنواع أصبح مستقرًا وأسرع 12×
في 22 يوليو 2026 أعلن فريق Oxc أن type-aware linting في Oxlint خرج من مرحلة التجربة وصار مستقرًا، بعد رحلة بدأت بنسخة ألفا في ديسمبر 2025. المحرّك خلف هذه القدرة هو tsgolint في نسخته السابعة، والمبني مباشرة على TypeScript v7.0.2 — نفس النواة المكتوبة بلغة Go التي غيّرت شكل مترجم TypeScript.
الخبر بسيط في ظاهره، لكنه يقفل آخر باب كان يمنع فرقًا كثيرة من الاستغناء عن typescript-eslint.
المشكلة: قاعدتان لا يمكن الجمع بينهما
أدوات الـ linting الحديثة المكتوبة بـ Rust — وOxlint في المقدمة — قدّمت سرعة لا تُقارن، لكنها كانت تعمل على مستوى الشكل النحوي فقط. أي أنها ترى الكود كشجرة نصية، ولا تعرف شيئًا عن الأنواع.
هذا يعني أن قواعد مثل no-floating-promises أو no-misused-promises كانت خارج نطاقها. وهذه ليست قواعد تجميلية؛ هي القواعد التي تمسك أخطاء await الناقص، والوعود المهجورة، والشروط التي لا تكون خاطئة أبدًا. النتيجة العملية: كثير من الفرق كانت تشغّل أداتين في الـ CI — Oxlint للسرعة، وtypescript-eslint للقواعد التي تحتاج معلومات الأنواع. وهذا يعني ضِعف وقت التنفيذ، وضِعف التهيئة، وضِعف الصيانة.
ما الذي تغيّر
tsgolint محرّك مكتوب بـ Go، بدأ كنموذج أوّلي من @auvred داخل مشروع typescript-eslint نفسه، ثم أُهدي لمنظمة Oxc. وبدلًا من إعادة بناء نظام الأنواع من الصفر، يعتمد المحرّك على النواة الرسمية typescript-go، فيحصل على تحليل أنواع مطابق للمترجم الرسمي بأداء لغة مُصرَّفة.
الأرقام المنشورة قيست على Apple M4 Pro بـ 12 نواة:
- VS Code — من 83.2 ثانية إلى 6.96 ثانية (أسرع 12×)
- TypeScript — من 27.2 ثانية إلى 1.94 ثانية (أسرع 14×)
- TypeORM — من 13.2 ثانية إلى 0.75 ثانية (أسرع 18×)
- Vue.js — من 12.3 ثانية إلى 0.95 ثانية (أسرع 13×)
والأهم من السرعة: التغطية. النسخة المستقرة تدعم 59 من 61 قاعدة type-aware موجودة في typescript-eslint، بزيادة 16 قاعدة منذ الألفا، منها no-unnecessary-condition وprefer-optional-chain وprefer-readonly وconsistent-return.
التطبيق العملي
التثبيت يحتاج حزمة إضافية إلى جانب Oxlint:
pnpm add -D oxlint oxlint-tsgolint@7ثم التشغيل من الطرفية:
# تشغيل القواعد التي تعتمد على الأنواع
pnpm oxlint --type-aware
# مع إظهار أخطاء مترجم TypeScript كذلك
pnpm oxlint --type-aware --type-check
# قياس زمن كل قاعدة على حدة
pnpm oxlint --type-aware --debug timingsأو تثبيت الإعداد في .oxlintrc.json ليكون سلوك الفريق والـ CI موحّدًا:
{
"options": {
"typeAware": true,
"typeCheck": true
},
"rules": {
"typescript/no-floating-promises": "error",
"typescript/no-misused-promises": "error",
"typescript/no-unnecessary-condition": "warn"
}
}الفرق بين الخيارين يستحق التوضيح: typeAware يفعّل القواعد التي تحتاج معلومات الأنواع، أما typeCheck فيضيف تشخيصات المترجم نفسه إلى مخرجات الـ linter — أي أنه يجعل الأداة الواحدة تغطي مسارين كانا منفصلين.
ملاحظات من الواقع
- قاعدتان غير مدعومتين من أصل 61. قبل حذف
typescript-eslintمن المشروع، الخطوة الصحيحة هي مقارنة القواعد المفعّلة فعليًا بقائمة المدعوم، لا الافتراض أن التغطية كاملة. - `typeAware` و`typeCheck` إعدادان جذريان فقط — لا يمكن تفعيلهما داخل قسم
overridesلمجلد معيّن. والأعلام في الطرفية تتجاوز ما في ملف الإعداد، وهذا مفيد في الـ CI ومربك عند تشخيص اختلاف النتائج محليًا. - الارتباط بنسخة TypeScript صريح. صيغة الإصدار
v7.0.2000تعني TypeScript v7.0.2 مع تحديث tsgolint رقم 0. أي أن ترقية TypeScript وترقية المحرّك مرتبطتان، ويجب أن تُدارا معًا في ملف الحزم. - حجم الحزمة أكبر. المحرّك ملف تنفيذي مستقل (نحو 21.8 ميجابايت على ARM64 Darwin بعد تقليص 26.6%). في صور Docker النحيفة هذا رقم يُحسب.
الخلاصة
الاتجاه واضح: أدوات JavaScript تنتقل من كتابتها بالجافاسكربت إلى كتابتها بلغات مُصرَّفة، وفحص الأنواع كان آخر ما بقي خارج هذا الانتقال. ومع استقرار tsgolint، صار من الممكن أن يعمل خط الـ CI بأداة واحدة تفهم الأنواع وتنتهي في ثوانٍ بدل دقائق.
القيمة الحقيقية ليست في الرقم، بل في أن الفحص الذي يستغرق ثوانٍ يُشغّل عند كل حفظ للملف — لا عند كل طلب دمج. والفحص الذي يعمل باستمرار هو الفحص الذي يمنع الخطأ قبل وصوله.
المصدر الأساسي: Type-Aware Linting Stable — oxc.rs