TypeScript لا يرى SVG؟ حل المشكلة نهائياً

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: "Cannot find module" — ألم مألوف؟

\n\n

أنت تكتب بلغة TypeScript، وتضيف إلى مشروعك أيقونة جميلة بصيغة SVG وتحاول استيرادها بالطريقة القياسية:

\n\n
import Logo from './assets/logo.svg';
\n\n

وفجأة يظهر لك TypeScript خطأ أحمر:

\n\n
Cannot find module './assets/logo.svg' or its corresponding type declarations.
\n\n

هل هذا مألوف؟ إذا واجهت هذه المشكلة ولو مرة واحدة، فأنت لست وحدك. سؤال "Unable to import svg files in typescript" على Stack Overflow حصد آلاف المشاهدات وعشرات الإجابات. المشكلة هي أن TypeScript افتراضياً لا يعرف كيفية التعامل مع الملفات غير البرمجية (SVG, PNG, CSS).

\n\n

في هذه المقالة، سنشرح شرحاً كاملاً مع الكود: لماذا يحدث الخطأ وكيفية إصلاحه نهائياً. ستتعرف على declaration files، وإعداد Webpack و Vite، وكذلك كيفية كتابة أنواع SVG بشكل صحيح في مشاريع React.

\n\n

لماذا لا يرى TypeScript ملفات SVG؟

\n\n

TypeScript هي لغة مكتوبة بشكل صارم (strictly typed). تتحقق من الأنواع في مرحلة التجميع. عندما تكتب import Logo from './logo.svg'، يتوقع TypeScript أن الوحدة ./logo.svg تصدر شيئاً بنوع معروف. لكن SVG ليس ملف TypeScript، بل هو XML. ليس لدى TypeScript وصف مدمج لوحدات SVG.

\n\n

من هنا يأتي الخطأ: لا يمكن للمترجم العثور على type declarations (إعلانات الأنواع) لهذا الملف.

\n\n

هناك ثلاث طرق رئيسية لحل المشكلة:

\n\n
    \n
  • الطريقة 1: إنشاء ملف إعلانات عام (.d.ts)
  • \n
  • الطريقة 2: استخدام Webpack/Vite مع المحملات (loaders) الصحيحة
  • \n
  • الطريقة 3: استيراد SVG عبر url أو raw (لحالات محددة)
  • \n
\n\n

سنشرح كل طريقة مع أمثلة كود.

\n\n

الطريقة 1: ملف declaration عام (الأكثر شيوعاً)

\n\n

هذا هو الحل من Stack Overflow الذي يعمل في 90% من الحالات. تقوم بإنشاء ملف بامتداد .d.ts (مثلاً src/declarations.d.ts أو src/svg.d.ts) وتعلن عن وحدة SVG.

\n\n

إليك الكود الأدنى:

\n\n
// src/declarations.d.ts\ndeclare module '*.svg' {\n  const content: string;\n  export default content;\n}
\n\n

ماذا يحدث هنا؟ نقول لـ TypeScript: "أي ملف بامتداد .svg هو وحدة تصدر افتراضياً نصاً (مسار الملف أو محتواه)".

\n\n

إذا كنت تستخدم React وتريد استيراد SVG كمكون React (عبر @svgr/webpack أو vite-plugin-svgr)، سيكون الإعلان مختلفاً:

\n\n
// src/declarations.d.ts\ndeclare module '*.svg' {\n  import React from 'react';\n  const SVGComponent: React.FC<React.SVGProps<SVGSVGElement>>;\n  export default SVGComponent;\n}
\n\n

هام: تأكد من أن ملف .d.ts مضمن في ملف tsconfig.json الخاص بك. عادةً يكفي أن يكون داخل src/، ولكن إذا لم يكن كذلك، أضف المسار في حقل include:

\n\n
// tsconfig.json\n{\n  "compilerOptions": {\n    // ... باقي الإعدادات\n  },\n  "include": ["src/**/*"]\n}
\n\n

بعد ذلك، سيختفي الخطأ "Cannot find module" وستتمكن من استيراد SVG كالمعتاد.

\n\n

الطريقة 2: إعداد Webpack أو Vite

\n\n

الإعلان العام هو نصف الحل فقط. لكي يعمل الاستيراد فعلياً في وقت التشغيل (في المتصفح)، تحتاج إلى إعداد أداة التجميع (bundler).

\n\n

لـ Webpack

\n\n

قم بتثبيت file-loader أو url-loader:

\n\n
npm install --save-dev file-loader
\n\n

أضف قاعدة في webpack.config.js:

\n\n
// webpack.config.                

المدونات

توصيات الكتب