ماژولهای جاوااسکریپتت دارن بهت دروغ میگن
خلاصهٔ کاملتر
نویسنده با یه مثال ساده شروع میکنه: یه ماژول ES یه بایندینگ زنده (live binding؛ یعنی متغیری که ایمپورت میکنی مستقیم به مقدار بهروزشده تو ماژول اصلی وصل میمونه، نه یه کپی ثابت) صادر میکنه، ولی نسخهی CommonJS همون کد ظاهراً یکسانه، نتیجهی متفاوتی میده. علتش اینه که «import» یه اسم رو مستقیم به بایندینگ ماژول مبدا وصل میکنه، ولی «require» فقط مقدار «module.exports» رو برمیگردونه که یه آبجکت معمولیه؛ اگه از توش دیستراکچر کنی، فقط مقدار همون لحظه رو کپی میگیری.
مثلاً وقتی یه تابع، مقدار صادرشده رو عوض میکنه:
import { status, start } from './state.mjs'
start()
console.log(status) // readyولی نسخهی CommonJS با دیستراکچرینگ همون رفتار رو نداره:
const { status, start } = require('./state.cjs')
start()
console.log(status) // startingنویسنده میگه این تفاوت فقط سر دیستراکچرینگ نیست؛ کل مفهوم «بایندینگ زنده» در برابر «مقدار کپیشده از یه آبجکت» رو نشون میده.
بخش بعدی مقاله سراغ ترتیب اجرا میره: ایمپورتهای استاتیک تو ESM، صرفنظر از اینکه کجای فایل نوشته شدن، قبل از اجرای بدنهی ماژول اصلی resolve و اجرا میشن؛ به همین خاطر بهش «هویستینگ ایمپورت» میگن. اما «require» تو CommonJS دقیقاً همونجایی که تو کد نوشته شده اجرا میشه، چون یه فراخوانی تابع معمولیه. نویسنده تأکید میکنه ماژولها فقط یهبار evaluate و تو کش نگه داشته میشن، پس require دوم همون export قبلی رو برمیگردونه، نه یه نسخهی تازه.
مقاله همچنین به «import()» پویا اشاره میکنه که برخلاف ایمپورت استاتیک، یه Promise برمیگردونه و میشه هر جای کد صداش زد؛ همین باعث میشه بشه از CommonJS به ESM پل زد. «await» در سطح بالای ماژول هم میتونه اجرای کل زنجیرهی وابستگیها رو معطل نگه داره. در آخر هم به وابستگیهای حلقوی میرسه و نشون میده CommonJS اجازه میده یه ماژول قبل از تموم شدن اجراش، export ناقصش برگرده - نکتهای که میتونه منبع باگهای سختپیدا بشه.
نکات کلیدی:
- ESM یه بایندینگ زنده صادر میکنه؛ CommonJS فقط یه مقدار (اغلب آبجکت) برمیگردونه که دیستراکچرینگش رفتار متفاوتی داره
- ایمپورتهای استاتیک تو ESM قبل از اجرای بدنهی ماژول resolve و اجرا میشن (هویستینگ)
- ماژولها فقط یهبار evaluate و کش میشن؛ require بعدی همون export قبلی رو برمیگردونه
- import() پویا یه Promise برمیگردونه و پل بین CommonJS و ESM رو فراهم میکنه
- CommonJS تو وابستگیهای حلقوی میتونه export ناقص برگردونه که میتونه منبع باگ باشه




