Node.js و پایتون

تفاوت ESM و CommonJS در Node.js؛ نقش mjs و cjs و type

نقش mjs و cjs و type در ESM و CommonJS، نمونهٔ import واقعی و تشخیص require is not defined را با توجه به نسخهٔ Node.js ببینید.

رایکت رایکت ۳ دقیقه مطالعه ۰ دیدگاه
تفاوت ESM و CommonJS در Node.js؛ نقش mjs و cjs و type

در Node.js، CommonJS معمولاً از require و module.exports استفاده می‌کند؛ ESM از import و export. اما انتخاب با جایگزین‌کردن یک کلمه تمام نمی‌شود: پسوند فایل، نزدیک‌ترین package.json و نسخهٔ Node تعیین‌کننده‌اند. برای رفع ابهام، قالب ماژول را صریح مشخص کنید.

۱. پسوند و type را کنار هم بخوانید

فایل یا قرارداد قالب مشخص
.mjs ESM، مستقل از type نزدیک
.cjs CommonJS، مستقل از type نزدیک
.js با type: module ESM در محدودهٔ همان package
.js با type: commonjs CommonJS در محدودهٔ همان package

در نسخه‌های جدید، برای ورودی‌های بدون نشانهٔ صریح امکان تشخیص بر اساس syntax هم مطرح است. بنابراین فرض همیشگی «هر .js بدون type حتماً در همهٔ شرایط CommonJS است» برای عیب‌یابی نسخه‌های مختلف کافی نیست. قرارداد صریح، نمونه را قابل‌فهم‌تر و نگهداری را ساده‌تر می‌کند.

۲. نمونهٔ کوچک با مرز روشن

در یک پوشهٔ آزمایشی، فایل hello.cjs این خروجی را صادر می‌کند:


module.exports = { greeting: 'hello' };

فایل esm-demo.mjs آن را به‌صورت default import می‌خواند:


import greeting from './hello.cjs';
console.log(greeting.greeting);

اجرای node esm-demo.mjs در Node ۲۴.۱۹.۰ خروجی hello داد. این مثال استفادهٔ محدود ESM از خروجی CommonJS را نشان می‌دهد؛ تضمین نمی‌کند هر named import از هر بستهٔ CommonJS کار کند.

۳. پیام require is not defined چه می‌گوید؟

اگر در یک فایل .mjs از require معمول CommonJS استفاده کنید، آن نام به‌طور عادی در محدودهٔ ESM تعریف نشده است. در آزمون ما، همین کاربرد در wrong-esm.mjs خطا داد. این نتیجه به معنی حذف‌شدن یا نصب‌نشدن فایل مقصد نیست.

  1. ابتدا پسوند فایلِ خطادار را بخوانید.
  2. نزدیک‌ترین package.json و type را بررسی کنید.
  3. شکل export مقصد و شکل import مبدأ را تطبیق دهید.
  4. به جای تغییر سراسری type، یک نمونهٔ مستقل و کوچک بسازید.

اگر به سازگاری ویژه نیاز دارید، ابزارهایی مانند createRequire قرارداد مشخص دارند؛ استفاده از آن‌ها باید با مستند نسخه و نیاز واقعی برنامه سنجیده شود، نه نسخه‌پیچی برای همهٔ خطاها.

۴. قواعدی که با نسخه تغییر کرده‌اند

در Nodeهای جدید، require می‌تواند بعضی ماژول‌های ESM همگام را در شرایط مشخص بارگذاری کند. بنابراین توصیهٔ قدیمی «require برای هر ESM همیشه ERR_REQUIRE_ESM می‌دهد» را قانون همیشگی ندانید. وجود top-level await، خروجی بسته و محدودیت نسخه همچنان مهم است.

برای import نسبی ESM، پسوند فایل را صریح بنویسید و قواعد resolution همان شاخهٔ Node را بخوانید. رفتار CommonJS در جست‌وجوی پسوند یا پوشه را خودکار به ESM تعمیم ندهید. این مقاله مهاجرت سراسری پروژه یا دستکاری build ابزارها را اجرا نمی‌کند.

۵. خطای syntax با خطای پیدا نشدن متفاوت است

نشانه سؤال اصلی
require is not defined آیا فایل در ESM اجرا می‌شود؟
Cannot use import statement outside a module قالب واقعی ورودی با syntax هم‌خوان است؟
ERR_MODULE_NOT_FOUND مسیر، پسوند و قرارداد exports درست است؟
Named export not found مقصد واقعاً همان نام را صادر می‌کند؟

نکته: تغییر type در package.json می‌تواند چندین فایل .js را هم‌زمان تحت تأثیر بگذارد. قبل از اعمال روی پروژه، فهرست ورودی‌ها، ابزار build و آزمون‌ها را در محیط جدا بررسی کنید.

۶. تصمیم قابل نگهداری

برای پروژهٔ تازه، یک قرارداد روشن انتخاب و همان را در فایل نمونه، اسکریپت اجرا و مستند پروژه ثبت کنید. در پروژهٔ موجود، ناسازگاری را در کوچک‌ترین مرز ممکن تشخیص دهید؛ rename تصادفی فایل و نصب دوبارهٔ همهٔ بسته‌ها دلیل قالب ماژول را روشن نمی‌کند. راهنمای استقرار موجود مرحلهٔ هاست را پوشش می‌دهد، اینجا تمرکز روی رفتار کد است.

۷. مسیر مطالعهٔ مرتبط

۸. منابع و روش بررسی

منابع رسمی در ۲۴ اکتبر ۲۰۲۶ بررسی شدند. مثال‌های کدِ این متن در Node.js نسخهٔ ۲۴.۱۹.۰ روی محیط محلی ایزوله بررسی شده‌اند؛ نصب روی هاست، اتصال دیتابیس یا کارایی تولید با این آزمایش اثبات نشده است.

این مطلب برایتان مفید بود؟
رایکت
نوشته شده توسط رایکت

تیم محتوای رایکت؛ آموزش‌ها و راهنماهای کاربردی هاست، دامنه و مدیریت سایت.

مطالب مرتبط

دیدگاه‌ها

نظر یا سوال خود را درباره این مطلب با ما در میان بگذارید

دیدگاه خود را بنویسید

aapanel
cloudlinux
cpanel
directadmin
jetbackup
laravel
mysql
virtualizor
vmware
wordpress