من میدانم که هیچ نمیدانم.
بررسی ماژولها (Modules) در جاوااسکریپت
با ماژولها میتونیم یک برنامه بزرگ رو به اجزای کوچیکتر تقسیم کنیم تا توسعه راحت بشه و هم خوانایی و نگهداری کد بالا بره. توی این قسمت با کلی نکته درباره ماژولها توی جاوااسکریپت آشنا میشیم.
سلام دوستان. ماژولها یکی از مهمترین و پراستفادهترین ویژگیها توی دنیای جاوااسکریپت مدرن هستن و امروزه تقریباً هر برنامهی بزرگ و کوچیکی از این ویژگی بهره میبره.
درک ماژولها و نحوهی کاربرد اونها توی جاوااسکریپت اهمیت زیادی داره. چون ابزارهای امروزی مثل فریمورکها خیلی فراوون از این ویژگی استفاده میکنن. توی این قسمت با ماژولهای جاوااسکریپت که توسط ES6 معرفی شدن آشنا میشیم و فواید اونها رو بررسی میکنیم.
توی این قسمت یاد میگیریم که:
- ماژول چیه؟
- کلمهکلیدی export
- export default چیه
- کلمهکلیدی import
- وارد کردن همه چیز
- وارد کردن عضو export default شده
- چرا از ماژولها استفاده کنیم
- استفاده از یک ماژول توی مرورگر
- تو چه مرورگرهایی میتونیم با تگ script با ماژولها کار کنیم
ماژول چیه؟ ?
یک جمله معروف درباره ماژولها یا بطور کلی اصل Separation of concerns (جداسازی وابستگیها) وجود داره:
نویسندگان خوب، کتابها رو به بخشها و فصلهای مجزا تقسیمبندی میکنن. برنامهنویسهای خوب، برنامه رو به بخشهای مختلف تقسیمبندی میکنن.
درست مثل یک کتابی که به فصلهای مجزا تقسیمبندی میشه، یک برنامه میتونه به قسمتهای مجزا تقسیم بندی بشه. به هر یک از این قسمتها میگن ماژول (Module).
یک ماژول معمولاُ مستقل از بخشهای برنامه عمل میکنه. توی جاوااسکریپت هر ماژول بصورت یک فایل جداگونه ذخیره میشه و میتونه بدون مشکل به یک ماژول دیگه و یا به هسته برنامه اضافه یا برداشته بشه. اعضای یک ماژول (متغیرها، توابع و ... ) فقط توی خود ماژول قابل دسترسی هستن و Global نیستن.
حالا وقت بررسی کردن این ویژگی توی جاوااسکریپت هست.
ما با کلمهکلیدی import
یک ماژول رو وارد برنامه میکنیم و فقط به اعضایی دسترسی داریم که توی ماژول export
شده باشن. پس اول Export رو بررسی میکنیم.
کلمهکلیدی export
با کلمهکلیدی export
میتونیم یک عضو از ماژول مثل یک متغیر رو قابل دسترسی کنیم. برای export
کردن متغیرها، توابع، کلاسها و ... از کلمهکلیدی export
قبل از اون عضو استفاده میکنیم. ابتدا یک فایل به اسم دلخواه مثلا artist.js
درست میکنیم با محتویات زیر:
export const name = "Mathias"
const favorites = ["Music", "Painting"];
export function play() {
return "?"
}
export class Draw {
start() {
return "?"
}
}
توی ماژول بالا اعضایی که قبل از تعریف اونها از کلمهکلیدی export
استفاده شده، قابل استفاده در بیرون ماژول هستن. پس به متغیر favorites
بیرون از ماژول نمیتونیم دسترسی پیدا کنیم.
اگه تعداد اعضای ما زیاد باشن، بجای نوشتن کلمه export
قبل از هر عضوی، میتونیم آخر ماژول اونها بصورت زیر Export کنیم:
const name = "Mathias"
const favorites = ["Music", "Painting"];
function play() {
return "?"
}
class Draw {
start() {
return "?"
}
}
export { name, play, Draw };
همچنین میشه یک عضو رو با نام دلخواه Export کرد. برای این کار از کلمهکلیدی as
هنگام Export کردن استفاده میکنیم:
const name = "Mathias"
function play() {
return "?"
}
export {
name,
play as playGuitar,
};
export default چیه؟
ما میتونیم مشخص کنیم به صورت پیشفرض، کدوم عضو در نظر گرفته بشه برای export
شدن. برای این کار از کلمهکلیدی default
بعد از export
استفاده میکنیم:
export default name = "Mathias"
export const favorites = ["Music", "Painting"];
یا به این صورت:
const name = "Mathias"
const favorites = ["Music", "Painting"];
export {
name as default,
favorites
}
بصورت پیشفرض چیزی که ماژول بالا تحویل میده متغیر name
هست، مگر اینکه موقع import
، عضوی که لازم داریم رو صراحتاً صدا بزنیم. تا الان فقط Export کردیم. حالا باید از چیزایی که Export کردیم استفاده کنیم. برای این کار از کلمهکلیدی import
استفاده میکنیم. توی ادامه با انواع نحوهٔ import
کردن آشنا میشیم.
کلمهکلیدی import
برای استفاده از ماژول artist
، یک فایل دیگه میسازیم به اسم app.js
با محتویات زیر:
import { name, playGuitar, Draw } from './artist';
console.log(name);
console.log(playGuitar());
ما توی خط اول آیتمهایی که از ماژول artist
احتیاج داریم رو جلوی کلمه import
و توی { }
نوشتیم. به نحوه آدرس دادن ماژول artist
دقت کنید. './artist'
یعنی این ماژول توی همین مسیر هست. همچنین اگه پسوند فایل ماژول js
هست، لازم نیست پسوند رو بنویسیم.
میتونیم اعضای یک ماژول رو با نام دلخواه Import کنیم. برای این کار از کلمهکلیدی as
هنگام وارد کردن استفاده میکنیم:
import { name as artistName, playGuitar, Draw } from './artist';
console.log(artistName);
وارد کردن همه چیز
اگه همهی اعضای یک ماژول رو لازم داریم از *
بصورت زیر استفاده میکنیم:
import * as myArtist from "./artist"
console.log(myArtist.name);
توی این کد همه اعضای ماژول از طریق myArtist
که اسم دلخواه ولی اجباری ما هست، مثل خط ۳ قابل دسترسی هستن.
وارد کردن عضو export default شده
توی قسمت export
دیدیم که یک ماژول میتونه یک عضو رو به عنوان پیشفرض export
کنه. حالا برای خوندن این مقدار پیشفرض بصورت زیر import
میکنیم:
import theArtistName from './artist';
همونطور که میبینید دیگه از { }
استفاده نشد. به عبارت دیگه، وقتی از { }
استفاده نمیکنیم، به این معنی هست که میخوایم عضو پیشفرض رو import
کنیم. همچنین theArtistName
یک مقدار دلخواه هست که میتونه هر چیزی باشه:
import table from './artist';
console.log(table); // Mathias
اگه در کنار عضو پیشفرض، به اعضای دیگه هم نیاز داشته باشیم به صورت زیر import
میکنیم:
import myCustomName, { play, Draw } from './artist';
چرا از ماژول استفاده کنیم؟
قابلیت نگهداری
از خوبیهای استفاده از ماژول اینه که قابلیت نگهداری (Maintainability) برنامهی ما بالاتر میره و بخشهای مختلف رو میشه راحتتر توسعه داد. تصور کنین توسعه و انسجام یک برنامه با یک فایل ۱۰۰ خطی بهتره یا چهار فایل ۲۵ خطی؟ شاید بگیم اینطوری داره تعداد فایلها بیشتر میشه. اما ما قسمتهای بیربط رو از هم جدا میکنیم تا کد ما معنادار بشه.
استفاده مجدد از کدها
یک تکه کد از برنامه که جاهای زیادی داره تکرار میشه رو میتونیم جدا و به یک فایل مجزا منتقل کنیم. هر وقت که خواستیم از این ویژگی استفاده کنیم کافیه فقط این فایل رو وارد کنیم.
استفاده از یک ماژول توی مرورگر
با type="module"
توی یک تگ script
میتونیم از یک ماژول توی مرورگر استفاده کنیم. ابتدا یک ماژول بصورت زیر درست میکنیم تا از اون توی مرورگر استفاده کنیم:
// add.js
export function add(x, y) {
return x + y;
}
حالا از ماژول بالا میتونیم بصورت زیر توی مرورگر استفاده کنیم:
<!-- ... -->
<body>
<script type="module">
import { add } from './add.js';
alert(add(5, 10));
alert(add(15, 13));
</body>
توی کد بالا چیزی که توی script
نوشتیم یک ماژول Local هست. باز هم میتونیم این ماژول رو ببریم توی یک فایل جدا و روی تگ script
با src="..."
بهش آدرس بدیم:
// app.js
import { add } from './add.js';
alert(add(1, 4));
alert(add(4, 29));
و توی HTML:
<!-- ... -->
<body>
<script type="module" src="./app.js">
</body>
نکته ۱: ماژولهایی که توی مرورگر تعریف میکنیم هم کپسوله هستن. یعنی به اجزای همدیگه دسترسی ندارن:
<!-- ... -->
<body>
<script type="module">
var x = 12;
alert(x); // x is not defined
</body>
نکته ۲: از یک منبع خارجی نمیتونیم import
کنیم و import
ماژولها توی مرورگر باید از همون منبع باشه. یعنی برای مثال اگه روی localhost هستیم، ماژولی که import
میکنیم باید روی همین localhost باشه. در غیر این صورت مرورگر اجازه دسترسی نمیده. پس کدها بالا رو توی مرورگر از طریق localhost باز کنین.
نکتهها
- حالت سختگیرانه یا Strict Mode توی یک ماژول همیشه فعال هست. پس لازم نیست از "use strict" استفاده کنیم.
- مقدار this توی ماژولها
undefined
هست.
Resources:
https://www.sitepoint.com/using-es-modules
https://alligator.io/js/modules-es6
https://javascript.info/modules-intro
https://www.freecodecamp.org/news/javascript-modules-a-beginner-s-guide-783f7d7a5fcc/
مطلبی دیگر از این انتشارات
بررسی مفهوم Execution Context در جاوااسکریپت - پشت پرده جاوااسکریپت (بخش اول)
مطلبی دیگر از این انتشارات
کنترل دسترسی مقیاس پذیر بر اینترنت اشیا (مقاله ترجمه شده)
مطلبی دیگر از این انتشارات
کاربردهای قراردادهای هوشمند / بخش اول