مقدمة: لماذا إعادة هيكلة الكود القديم ليست رفاهية بل ضرورة
\nفي تطوير الويب الحديث، أصبح TypeScript المعيار الفعلي للمشاريع الكبيرة. ومع ذلك، تواجه العديد من الشركات والشركات الناشئة مشكلة: قاعدة الكود المكتوبة بلغة JavaScript النقية أو الإصدارات المبكرة غير الصارمة من TypeScript تتحول بمرور الوقت إلى "مستنقع". غياب الأنواع، والوظائف المتضخمة، والتبعيات الضمنية، والأنماط القديمة - كل هذا يبطئ التطوير ويزيد من عدد الأخطاء.
\nإعادة هيكلة الكود القديم هي عملية تحسين البنية الداخلية للبرنامج دون تغيير سلوكه الخارجي. في سياق TypeScript، تكتسب قيمة خاصة: نحن لا ننظف الكود فحسب، بل نحصل أيضًا على نظام أنواع قوي يمنع الأخطاء في مرحلة التجميع. في هذه المقالة، سنستعرض خطة إعادة هيكلة خطوة بخطوة، من التحليل الأولي إلى الاختبار النهائي، مع أمثلة حقيقية على TypeScript.
\n\n1. التحليل والجرد: من أين نبدأ؟
\nالخطوة الأولى والأكثر أهمية هي فهم ما نتعامل معه. لا يمكنك ببساطة أخذ كل شيء وإعادة كتابته دفعة واحدة. هذا طريق نحو الفوضى وإضاعة الوقت. النهج الصحيح هو إجراء تدقيق لقاعدة الكود.
\n- \n
- حدد "النقاط الساخنة". ابحث عن الوحدات التي يتم تغييرها في أغلب الأحيان أو تحتوي على أكبر عدد من الأخطاء. استخدم أدوات مثل
git logأو SonarQube. \n - اكتشف الأنواع الضمنية. في كود JS القديم، غالبًا ما توجد وظائف تقبل
anyأو تستخدم@ts-ignore. قم بإعداد قائمة بهذه الأماكن. \n - تحقق من التبعيات. المكتبات القديمة (مثل
lodash3.x) قد تعيق الانتقال إلى واجهات برمجة التطبيقات الحديثة لـ TypeScript. \n - اكتب الاختبارات. قبل أي إعادة هيكلة، قم بتغطية الأجزاء الرئيسية من الكود بالاختبارات. هذه هي "شبكة الأمان" الخاصة بك. \n
مثال: لديك وظيفة بلغة JS تعالج بيانات المستخدم. بدلاً من إعادة كتابتها فورًا، أضف اختبارات وحدة باستخدام Jest أو Vitest:
\n// legacy.js\nfunction processUser(data) {\n return { name: data.name, age: data.age + 1 };\n}\n\n// test.js\nimport { processUser } from './legacy';\ntest('processUser increments age', () => {\n expect(processUser({ name: 'Alice', age: 30 })).toEqual({ name: 'Alice', age: 31 });\n});\n\nفقط بعد ذلك يمكنك البدء في إعادة الهيكلة.
\n\n2. الترحيل التدريجي إلى كتابة الأنواع الصارمة
\nيقدم TypeScript عدة مستويات من الصرامة. بالنسبة للكود القديم، يُوصى بالبدء بـ "strict": false وزيادة المستوى تدريجيًا. التفعيل المفاجئ لجميع الخيارات قد يكسر مئات الملفات.
الخطوات الرئيسية:
\n- \n
- فعّل
noImplicitAny. سيجبرك هذا على تحديد الأنواع بوضوح لجميع المعلمات والقيم المُرجعة. قد يكون هذا مؤلمًا في البداية، لكنه الطريقة التي ستجد بها أخطر الأماكن. \n - استخدم
strictNullChecks. أحد الأسباب الرئيسية للأخطاء هوnullوundefined. سيجبرك هذا العلم على معالجتها بشكل صريح. \n - أضف
noUnusedLocalsوnoUnusedParameters. سيساعدان في إزالة الكود الميت. \n
مثال على إعادة هيكلة وظيفة ذات أنواع ضمنية:
\n// قبل إعادة الهيكلة (JS قديم)\nfunction calculateTotal(price, tax) {\n return price + (price * tax);\n}\n\n// بعد إعادة الهيكلة (TypeScript)\ninterface PriceData {\n price: number;\n tax: number;\n}\n\nfunction calculateTotal({ price, tax }: PriceData): number {\n if (price < 0 || tax < 0) {\n throw new Error('Price and tax must be non-negative');\n }\n return price + (price * tax);\n}\n\nلاحظ: لم نضف الأنواع فقط، بل جعلنا واجهة برمجة التطبيقات أكثر أمانًا باستخدام واجهة والتحقق من الصحة.
\n\n