ماژول ها (Modules) در زبان برنامه نویسی TypeScript
ماژول ها با هدف سازماندهی کدهای تایپ اسکریپت طراحی شده اند. به طور گسترده ماژول ها به دو دسته تقسیم می شوند:
- ماژول های داخلی (Internal Modules)
- ماژول های خارجی (External Modules)
ماژول های داخلی
ماژول های داخلی در نسخه های قدیمی تر زبان TypeScript معرفی شده اند. این ماژول ها برای گروه بندی منطقی کلاس ها، اینترفیس ها، توابع و غیره در داخل یک بسته واحد و استفاده از آن در سایر ماژول ها استفاده می شدند. در آخرین نسخه زبان تایپ اسکریپت، مفهوم گروه بندی منطقی با نام namespace معرفی شده است. بنابراین ماژول های داخلی منسوخ شدند و به جای آن ها می توانیم از namespace استفاده کنیم. ماژول های داخلی هنوز هم پشتیبانی می شوند، اما توصیه می شود از namespace استفاده شود.
سینتکس ماژول داخلی (گروه بندی قدیمی):
1 2 3 4 5 | module TutorialPoint { export function add(x, y) { console.log(x+y); } } |
سینتکس فضای نام (گروه بندی جدید):
1 2 3 | namespace TutorialPoint { export function add(x, y) { console.log(x + y);} } |
خروجی جاوا اسکریپت برای هر دو کد فوق مشابه است:
1 2 3 4 5 6 7 | var TutorialPoint; (function (TutorialPoint) { function add(x, y) { console.log(x + y); } TutorialPoint.add = add; })(TutorialPoint || (TutorialPoint = {})); |
ماژول خارجی
ماژول های خارجی به منظور مشخص کردن و بارگذاری وابستگی بین چند فایل js بوجود آمده اند. اگر فقط یک فایل js وجود داشته باشد، استفاده از ماژول های خارجی مناسب نیست. قبلا مدیریت وابستگی بین فایل های js توسط تگ مرورگر انجام می شد. مشکلی که این تگ ها دارند، این است که قابل گسترش نیستند. به معنا که این تگ ها فایل ها پشت سر هم بارگذاری می کنند و گزینه برای بارگذاری ناهمگام (asynchronous) ندارند. دو روش برای بارگذاری وابستگی ها از یک فایل js وجود دارد:
- سمت کلاینت – RequireJs
- سمت سرور – NodeJs
انتخاب یک Module Loader
برای بارگذاری فایل های js خارجی ما به یک Module Loader نیاز داریم. Module Loader یک کتابخانه js دیگری خواهد بود. برای مرورگر رایج ترین کتابخانه مورد استفاده RequieJS است که خاصیت های AMD یا همان Asynchronous Module Definition را پیاده سازی کرده است. در AMD فایل ها به جای این که پشت سر هم بارگذرای شوند، به صورت جداگانه بارگذاری می شوند، حتی اگر به یک دیگر وابستگی داشته باشند.
تعریف یک ماژول خارجی
زمانی که بخواهیم یک ماژول خارجی را با استفاده از CommonJS یا AMD تعریف کنیم، هر فایل به عنوان یک ماژول در نظر گرفته می شود. بنابراین استفاده از ماژول داخلی با ماژول خارجی امری اختیاری خواهد بود. اگر قصد دارید تا سیستم ماژول بندی TypeScript را از AMD به CommonJS تغییر دهید، برخلاف زبان JavaScript فقط باید یک flag کامپایلر را عوض کنید. در ادامه می توانید سینتکس مربوط به تعریف یک ماژول خارجی با استفاده از کلمات کلیدی export و import را مشاهده کنید:
1 2 3 4 | //FileName : SomeInterface.ts export interface SomeInterface { //code declarations } |
برای اعلان ماژول تعریف شده در یک فایل دیگر، از کلمه کلیدی import استفاده می کنیم. مانند نمونه زیر:
1 | import someInterfaceRef = require(“./SomeInterface”); |
مثال:
برای درک بهتر به مثال زیر توجه کنید:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // IShape.ts export interface IShape { draw(); } // Circle.ts import shape = require("./IShape"); export class Circle implements shape.IShape { public draw() { console.log("Cirlce is drawn (external module)"); } } // Triangle.ts import shape = require("./IShape"); export class Triangle implements shape.IShape { public draw() { console.log("Triangle is drawn (external module)"); } } // TestShape.ts import shape = require("./IShape"); import circle = require("./Circle"); import triangle = require("./Triangle"); function drawAllShapes(shapeToDraw: shape.IShape) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle()); |
دستور مربوط به کامپایل کردن فایل TypeScript اصلی با سیستم AMD:
1 | tsc --module amd TestShape.ts |
بعد از کامپایل کدهای زیر تولید خواهند شد.
فایل IShape.js:
1 2 3 | //Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { }); |
فایل Circle.js:
1 2 3 4 5 6 7 8 9 10 11 12 | //Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { var Circle = (function () { function Circle() { } Circle.prototype.draw = function () { console.log("Cirlce is drawn (external module)"); }; return Circle; })(); exports.Circle = Circle; }); |
فایل Triangle.js:
1 2 3 4 5 6 7 8 9 10 11 12 | //Generated by typescript 1.8.10 define(["require", "exports"], function (require, exports) { var Triangle = (function () { function Triangle() { } Triangle.prototype.draw = function () { console.log("Triangle is drawn (external module)"); }; return Triangle; })(); exports.Triangle = Triangle; }); |
فایل TestShape.js:
1 2 3 4 5 6 7 8 9 10 | //Generated by typescript 1.8.10 define(["require", "exports", "./Circle", "./Triangle"], function (require, exports, circle, triangle) { function drawAllShapes(shapeToDraw) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle()); }); |
دستور مربوط به کامپایل کردن فایل TypeScript اصلی با سیستم CommonJS:
1 | tsc --module commonjs TestShape.ts |
بعد از کامپایل کدهای زیر تولید خواهند شد.
فایل Circle.js:
1 2 3 4 5 6 7 8 9 10 11 | //Generated by typescript 1.8.10 var Circle = (function () { function Circle() { } Circle.prototype.draw = function () { console.log("Cirlce is drawn"); }; return Circle; })(); exports.Circle = Circle; |
فایل Triangle.js:
1 2 3 4 5 6 7 8 9 10 | //Generated by typescript 1.8.10 var Triangle = (function () { function Triangle() { } Triangle.prototype.draw = function () { console.log("Triangle is drawn (external module)"); }; return Triangle; })(); exports.Triangle = Triangle; |
فایل TestShape.js:
1 2 3 4 5 6 7 8 9 | //Generated by typescript 1.8.10 var circle = require("./Circle"); var triangle = require("./Triangle"); function drawAllShapes(shapeToDraw) { shapeToDraw.draw(); } drawAllShapes(new circle.Circle()); drawAllShapes(new triangle.Triangle()); |
خروجی مثال:
1 2 | Cirlce is drawn (external module) Triangle is drawn (external module) |
هیچ نظری ثبت نشده است