ماژول و namespace: آشنایی با ES Modules

Module and Namespace: ES Modules

20 مرداد 1399
ماژول و namespace: آشنایی با ES Modules

در جلسه قبل با namespace ها در تایپ اسکریپت آشنا شدیم و با اینکه قابلیت بسیار خوبی برای تقسیم کد بین فایل ها هستند، دردسر کمی ندارند. مثلا اگر به فایل آماده شده ای که جلسه قبل به شما دادم نگاهی بیندازید، باید تمام کدهای مورد نیازمان را به صورت دستی جدا کرده و به صورت دستی وارد کنیم و مطمئن بشویم که قسمت های مورد نیازمان را export کرده ایم. خوشبختانه ماژول های ES6 کار ما را راحت تر می کنند. برای ادامه کار حتما فایل جلسه قبل را دانلود کنید (اگر نکرده اید، روی این لینک کلیک کنید) تا کار را بر اساس این فایل ادامه دهیم. من در قدم اول وارد پوشه models و سپس فایل drag-drop.ts می شوم. کد آن در حال حاضر به شکل زیر است:

// Drag & Drop Interfaces
namespace App {
    export interface Draggable {
        dragStartHandler(event: DragEvent): void;
        dragEndHandler(event: DragEvent): void;
    }

    export interface DragTarget {
        dragOverHandler(event: DragEvent): void;
        dropHandler(event: DragEvent): void;
        dragLeaveHandler(event: DragEvent): void;
    }
}

من namespace را حذف می کنم و به شکل زیر از ES6 Modules استفاده می کنم:

// Drag & Drop Interfaces

export interface Draggable {
  dragStartHandler(event: DragEvent): void;
  dragEndHandler(event: DragEvent): void;
}

export interface DragTarget {
  dragOverHandler(event: DragEvent): void;
  dropHandler(event: DragEvent): void;
  dragLeaveHandler(event: DragEvent): void;
}

در واقع کلیدواژه export یک دستور جاوا اسکریپتی است و در کد بالا می گوید که این دو interface را export می کند. به همین سادگی از ماژول های ES6 استفاده کرده ایم! حالا از آنجایی که ما در فایل های  project-item.ts و project-list.ts به این interface ها نیاز داریم باید آن ها را وارد کنیم. مثلا من وارد فایل project-item.ts می شوم و به شکل زیر آن ها را وارد می کنم:

import { Draggable } from '../models/drag-drop.js';

یعنی ما از Draggable در این فایل استفاده می کنیم. توجه کنید که من پسوند را js گذاشته ام نه ts به دلیل اینکه این کد مستقیما وارد فایل کامپایل شده شما می شود و برنامه به دنبال فایل جاوا اسکریپتی خواهد بود. به همین صورت بقیه موارد را نیز import می کنیم:

import { Draggable } from '../models/drag-drop.js';
import { Project } from '../models/project.js';
import { Component } from './base-component.js';
import { autobind } from '../decorators/autobind.js';

البته حواستان باشد که حتما namespace ها را حذف کنید. همین کار را خودتان برای تمام کدها انجام بدهید (من فایل نهایی را برایتان قرار می دهم). البته قبل از ادامه بحث چند نکته کوتاه در مورد این ماژول ها می گویم. فرض کنید کد زیر را داشته باشیم:

export const person = {
  name: 'John',
  age: 30
}

export function sayHello() {
  return `Hello ${person.name}`;
}

برای وارد کردن آن در یک فایل دیگر می گوییم:

// ES2015 Module
import { person, sayHello } from './mymodule2';

بنابراین باید با ویرگول موارد وارد شده را از هم جدا کنیم. همچنین اگر تعداد ماژول های شما زیاد بود می توانید به شکل زیر عمل کنید:

import * as mod from './mymodule2';

با این کار دیگر نیازی نیست که هر ماژول را به اسم وارد کنید، بلکه همه به صورت یکجا وارد می شوند. زمانی که می گوییم as mod یعنی یک نام مستعار به نام mod را برای این import انتخاب کرده ایم، یعنی تمام ماژول های موجود در این فایل را با نام مستعار mod وارد این فایل کن. شما می توانید این نام را هر چیزی بگذارید. مثال استفاده:

import * as mod from './mymodule2';

console.log(mod.person.name);

console.log(mod.sayHello());

حالا به کد زیر نگاه کنید:

export const person = {
  name: 'John',
  age: 30
}

export function sayHello() {
  return `Hello ${person.name}`;
}

const greeting = 'Hello World';
export default greeting;

زمانی که یک ماژول را به عنوان default تعیین و export کنیم (مانند رشته greeting در کد بالا) دیگر نیازی نیست که آن را درون علامت های {} بگذاریم. مثال استفاده در فایل app.js:

import greeting from './mymodule2';

console.log(greeting);

نکته: در هر فایل فقط می توانید یک default داشته باشید (البته می توانید export های دیگری هم در کنارش داشته باشید اما default فقط یکی خواهد بود). معمولا از Default زمانی استفاده می شود که فقط یک export درون فایل خود داشته باشیم.

البته شما می توانید این نام مستعار را در حالت عادی نیز استفاده کنید:

import { person as AliasPerson } from './mymodule2';

این ها چند نکته کوتاه بودند که دوست داشتم به خاطر بسپارید (در جلسه بعد بیشتر در این مورد صحبت می کنیم. البته حالا اگر کدهایمان را کامپایل کنیم چیزی نمایش داده نمی شود. باید دوباره به tsconfig.json برویم. مشکل اول اینجاست که دیگر نباید از ماژول amd استفاده نماییم بلکه ماژول هدف ما es2015 (همان es6) می باشد:

  "compilerOptions": {
    /* Basic Options */
    "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
    "module": "es2015" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,

با این کار به تایپ اسکریپت می گوییم که import های ما را به هیچ نوع دیگری از import تبدیل نکن (ما انواع مختلف سیستم های module را برای جاوا اسکریپت داریم مثل commonjs و amd و harmony و الی آخر) بلکه آن ها را به همین صورت ES6 حفظ کن. همچنین توجه داشته باشید که target شما روی ES6 باشد. حالا دوباره outfile را کامنت کنید چرا که این قابلیت در ES6 Module ها پشتیبانی نمی شود. با این کار اگر فایل های خود را کامپایل کنید، دقیقا ساختار پوشه src را در پوشه dist مشاهده خواهید کرد که تعداد زیادی فایل و پوشه است اما در index.html فقط باید app.js را وارد کنید:

    <script type="module" src="dist/app.js"></script>

توجه داشته باشید که من defer را حذف کرده ام و سپس type را روی module گذاشته ام. بدین شکل به مرورگر اعلام می کنیم که کدهای ما از نوع ماژولار هستند بنابراین مرورگر می فهمد که باید چکار کند. با اینکه ما فقط فایل App.js را وارد کرده ایم اما خود مرورگر متوجه می شود که فایل های دیگر را نیز دانلود کند. این روش بسیار راحت تر است اما تعداد درخواست ها به سمت سرور را بسیار زیاد می کند! این مشکل را بعدا با webpack حل خواهیم کرد.

من فایل آماده شده این جلسه را برایتان قرار می دهم. بهتر است آن را دانلود کرده و کدهایش را با کدهای خودتان مقایسه کنید تا به مشکلات کارتان پی ببرید. دانلود فایل نهایی این جلسه.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش جامع تایپ اسکریپت توصیه می‌کند:
نویسنده شوید

دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.

ما را دنبال کنید
اینستاگرام روکسو تلگرام روکسو ایمیل و خبرنامه روکسو