جاوااسکریپت هم مثل هر زبان دیگهای به سیستمهای ماژولبندی نیاز داره. ینی چی؟ یعنی سیستمی که بتونه کدها رو در چند فایل نگه داره و از یه فایل، فایل دیگه رو صدا بزنه و از کدش استفاده کنه. اینطوری میتونیم از کدها هرچقد بخوایم استفاده کنیم. الان قراره بریم سراغ سیستمهای ماژولبندی جاوااسکریپت و دوتا از معروفترینها که CommonJs و ESM هستن؛ معرفیشون کنیم و تفاوتهاشون رو بررسی کنیم تا ببینیم در هر حالتی بهترین انتخاب چیه؟
ماژولها در javascript چی هستن؟
ماژولها بلوکها یا تکه کد های قابل استفاده هستن که میتونن بین فایلها جا به جا بشن(یعنی میتونن از جایی به یک فایل import(وارد) بشن، یا از یک فایل export(خارج) بشن تا در دسترس بقیه فایلها قرار بگیرن). این سیستم ماژول باعث میشه ساختار فایلها قابل کنترلتر بشه و کار کردن و تغییر و توسعه دادنشون سادهتر باشه. در اول جااسکریپت این سیستمها رو نداشت تا وقتی که …
CommonJS وارد میشود:
دور و بر سال 2009 commonjs معرفی شد. بعد توسط تیم node.js توسعه پیدا کرد و چیزی که الان میبینیم بوجود اومد.
مهمترین ویژگیهای commonjs اینا هستن:
- Synchronous Loading: این سیستم ماژولها رو بصورت خطی دانلود میکنه(یعنی هر ماژول بعد از اتمام ماژول قبل)
- CommonJS از require برای صدا زدن(import) ماژولها و از
module.exports
برای صادر کردن(export) ماژولها استفاده میکنه تا بقیه فایلها بتونن ازش استفاده کنن. مثالش اینطوریه:
// module-name.js module.exports = { /* ... */ } // index.js // صدا زدن کل ماژول const module = require("./module-name.js"); module.method();
- ماژولها بعد از لود شدن در runtime اجرا میشن: توضیح این بخش که چرا مهمه رو در ادامه میگم:
اما یه نکته مهم: چون ()require بوسیله node.js توسعه پیدا کرده بطور مستقیم توی مرورگرها پشتیبانی نمیشه. ساده بگم کار نمیکنه و برای اینکه کار کنه باید از ابزارهای بسته بندی استفاده کنیم؛ این ابزارها دنبال ()require میگردن و اونو با تیکه کد لازم برای اجرا جایگزین میکنن. و در نهایت تمام فایلهای جاوااسکریپت مورد نیاز برنامه وب رو به یک فایل جاوااسکریپت با همه جاوااسکریپت برنامه که بهش میگیم bundle متصل میکنن. نمونهای از این ابزارها Webpack یا Parcel هستن.
ESM چیه و چطور کار می کنه؟
در سال 2015 که ECMAScript 2015(یا ES6) رو نمایی شد. با ورود این نسخه ویژگیهای جدید خیلی زیادی اضافه شد که یکی از اونها پشتیبانی داخلی جاوااسکریپت از یه ماژول سیستم بود. ESM مخفف ECMAScript Module هست. ویژگیها و سینتکس اون رو بررسی کنیم:
- Asynchronous Loading: لود شدن ماژولها در ESM بصورت Asynchronous هست(این یعنی همه ماژولهایی که نیاز هست بصورت async و باهم دانلود میشه. به عبارتی ماژول بعدی صبر نمیکنه لود شدن قبلی تموم شه تا لود بشه. بلکه باهم لود میشن).
- ESM از کلمات کلیدی
import
و export برای صدا زدن(همون import) و صادر کردن(همون export) استفاده میکنه.
// module.js export const data = 42; export const method = () => console.log("Hello"); // index.js import { data, method } from "./module.js";
- Static Analysis: ماژولها در compile time تجزیه میشن. که باعث بهینه سازی بهتر میشه. بعدا همونطور که گفتم توی مقایسه بیشتر توضیح میدم.
خب خوبی این سیستم چیه؟ یکی اینکه توی مرورگرهای مدرن و node.js(از ورژن12) بصورت پیشفرض پشتیبانی میشه.
حالا یه مقایسه بین این دوتا ببینیم:
شاید این مقایسه هم واستون جالب باشه: پکیج منیجرهای javascript: مقایسه pnpm, yarn, npm
تفاوتهای بین CommonJS و ESM:
- هر دو سیستم توی node.js پشتیبانی میشن. پس وقتی از node.js استفاده میکنیم میتونیم از هردوش استفاده کنیم.
- esm بصورت async لود کردن رو انجام میده و sync رو هم پشتیبانی میکنه. در حالی که اون یکی این پشتیبانی رو نداره و ممکنه روی عملکرد تاثیر منفی بزاره.
- در حالت عادی commonjs با مرورگر سازگاری نداره.
- ESM اجازه میده شما از یه url یا cdn یه ماژول رو import کنید. commonjs این ویژگی رو نداره.
- ESM با در نظر گرفتن یه ویژگی به اسم tree-shaking طراحی شده. چیکار میکنه؟ کدهایی که استفاده نمیشن رو حذف میکنه. خب اینطوری بهینه تره
همونطور که گفتم اینها صرفا خلاصهای از معرفی و تفاوتها بود و اگه علاقهمندید میتونید خیلی عمیقتر بررسیش کنید. اما یه مورد دیگه که گفتم توضیح میدم این بود که تجزیه ماژولها در سیستم ESM در compile time انجام میشه. این به موتور جاوااسکریپت اجازه میده اطلاعاتی درمورد ساختار ماژولها مثل توابع یا متغیرهایی که استفاده نشدن رو پیدا کنه و در مرحله بعد اونا رو بهینه کنه و سپس اجرا … احتمالا با این توضیح درمورد ساختار تجزیه و اجرای موتور جاوااسکریپت کمی گیج بشید ولی بخشی که گفتم اینطوری کار میکنه و با این ساختار موتور باعث میشه بهینه سازی انجام بشه. این قضیه درمورد commonjs اتفاق نمیافته.
مقاله مرتبط با این مقاله: جاوااسکریپت یا تایپاسکریپت؟ راهنمای انتخاب
با تمام چیزهایی که گفتیم و اینکه بنظر ESM آینده ماژولهای javascript هست، ممکنه برای کار با کتابخانهها یا ابزارهایی که فقط از commonjs استفاده کنن یا به دلایل دیگه، مجبور باشیم از commonjs استفاده کنیم، مخصوصا در node.js. در یان بین ممکنه اسمهای دیگهای هم بشنوید ولی مهمترین سیستمها همینایی بود که بررسی کردیم و میبینیدش. به هر حال امیدوارم برای هر پروژهای درست انتخاب کنیم. خوشحال میشم نظرتون یا پیشنهاداتتون رو درمورد این مقاله بدونم.