Node.js / دليل حلول تحريري

عدم العثور على الوحدة وعدم توافق CommonJS مع ESM

افصل فشل حل المسار وصيغة الوحدة وعقد التصدير قبل تغيير تثبيت الحزم.

وقت القراءة التقريبي: 3 دقيقةتاريخ مراجعة المحتوى

قاعدة معرفة للقراءة فقط · بلا تعليقات عامة

تعرّف على الأعراض

يبلغ البدء ERR_MODULE_NOT_FOUND أو MODULE_NOT_FOUND أو require is not defined أو غياب تصدير مسمّى. وقد يعمل ملف من مجلد ويفشل من آخر. تصف الرسائل مراحل مختلفة: تحديد الهدف وتفسير صيغته ومطابقة صادراته. لا تصلح إعادة التثبيت المراحل الثلاث كلها.

افهم الأسباب المحتملة

  • تشمل الأسباب امتدادا نسبيا مفقودا وحالة أحرف خاطئة وحلا من وحدة غير مقصودة وقيد صادرات حزمة أو require داخل .mjs. يؤثر type في أقرب package.json على .js؛ وتزيل .mjs و.cjs الصريحتان الغموض. غياب حزمة مثبتة سبب واحد فقط.

تصنيف الرسالة الدقيقة

سجل إصدار Node والأمر والامتداد وأقرب package.json والملف المستورد الفعلي. افحص المحدد المطلوب قبل التعديل. يُحل ./math.mjs من الوحدة المستوردة، بينما يستخدم اسم الحزمة المجرد حل الحزم وقد تقيده exports. وتختلف قاعدة مجلد العمل للقراءة النسبية من نظام الملفات. في نظام يراعي الحالة يختلف Math.mjs عن math.mjs. افحص هذه الحقائق قراءة فقط قبل إضافة خيارات أو تغيير المشروع كله.

إصلاح صيغة الوحدة بوعي

استخدم import وexport في ESM مع الامتدادات النسبية. واستخدم require وmodule.exports في CommonJS بصيغة مختارة صراحة. لا تعد تسمية المشروع كله لإسكات خطأ واحد؛ فقد تحتاج المكتبات والاختبارات والإعدادات إلى صيغ مختلفة. يوضح المقطع غير القابل للتشغيل عدم توافق الصيغة وليس برنامجا كاملا. ولا يُصلح بتثبيت حزمة اسمها node:path؛ فالوحدات المدمجة تأتي مع Node وتوضح السابقة مصدرها.

javascript مثال تشخيصي: إصلاح صيغة الوحدة بوعي
// broken.mjs: intentionally invalid in this module format
const { join } = require('node:path');

يستخدم المقطع المقصود require الخاصة بـ CommonJS داخل ESM وهو موسوم غير قابل للتشغيل. استبدله باستيراد join من node:path في مصدر ESM.

التحقق من حد وحدة حقيقي

ينشئ المثال الكامل ملفي مصدر صغيرين في مجلده المؤقت. يستورد المستهلك تصديرا مسمّى بمحدد نسبي .mjs، ويحمل الأصل المستهلك عبر pathToFileURL. النتيجة12. يبقي التوليد المؤقت كل الملفات المطلوبة ظاهرة في عرض واحد؛ وتعيش الوحدات العادية في المستودع. إذا لم تصدر حزمة مسارا فرعيا فاستخدم مدخلها العام الموثق بدلا من ملفات داخلية قد ينقلها إصدار لاحق.

javascript مثال تشخيصي: التحقق من حد وحدة حقيقي
import { mkdtemp, writeFile, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { pathToFileURL } from 'node:url';
const dir = await mkdtemp(join(tmpdir(), 'esm-guide-'));
try {
  await writeFile(join(dir, 'math.mjs'), 'export const triple = n => n * 3;');
  const app = join(dir, 'app.mjs');
  await writeFile(app, "import { triple } from './math.mjs'; export const result = triple(4);");
  const { result } = await import(pathToFileURL(app).href);
  console.log(result);
} finally { await rm(dir, { recursive: true, force: true }); }
الناتج المتوقع
12

يتطابق الامتداد النسبي والتصدير المسمّى. وتمثل pathToFileURL مسار الملف بأمان كرابط استيراد.

تغيير الاعتماديات عند الحاجة

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

تحقق من نجاح الإصلاح

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

امنع تكرار المشكلة

  • اختر صيغا صريحة واحفظ الامتدادات والحالة بدقة ووثّق مداخل الحزم وأبعد آثار البدء عن الوحدات المعاد استخدامها. احفظ البيان والقفل معا واختبر الاستيراد في التكامل المستمر لا على جهاز المطور فقط.

المراجع الرسمية