به فصل جدید این دوره آموزش جامع تایپ اسکریپت خوش آمدید. ما در فصل قبل یک پروژه دموی drag & drop را از صفر نوشتیم و یکی از مشکلاتی که بر سر راه ما بود، طولانی شدن فایل app.ts بود. در واقع ما تمام کدهای خود را درون یک فایل نوشتیم به همین دلیل پیدا کردن آن ها بسیار سخت شده بود. برای حل این مشکل سه راه حل داریم:
من از روش اول اصلا استفاده نمی کنم چرا که هیچ مزیتی ندارد ولی روش های دوم و سوم را در همین دوره آموزشی بررسی خواهیم کرد. بیایید با namespace ها شروع کنیم. به فایل App.ts از پروژه قبل بروید (در قسمت قبل لینک دانلود سورس کد آن را برایتان قرار داده بودم). من یک فایل جدید به نام drag-drop-interfaces.ts را ایجاد می کنم و سپس interface های زیر را از فایل app.ts به این فایل جدید منتقل می کنم:
// Drag & Drop Interfaces interface Draggable { dragStartHandler(event: DragEvent): void; dragEndHandler(event: DragEvent): void; } interface DragTarget { dragOverHandler(event: DragEvent): void; dropHandler(event: DragEvent): void; dragLeaveHandler(event: DragEvent): void; }
اما با این کار تفاوت چندانی ایجاد نکرده ایم. ما باید درون فایل drag-drop-interfaces.ts یک namespace جدید ایجاد کنیم و این interface ها را درون آن قرار بدهیم:
// Drag & Drop Interfaces namespace DDInterfaces { interface Draggable { dragStartHandler(event: DragEvent): void; dragEndHandler(event: DragEvent): void; } interface DragTarget { dragOverHandler(event: DragEvent): void; dropHandler(event: DragEvent): void; dragLeaveHandler(event: DragEvent): void; } }
همانطور که می بینید برای تعریف namespace ها باید از کلیدواژه namespace استفاده کرده و سپس نامی برای آن انتخاب کنیم. من نام DDInterfaces را برای آن انتخاب کرده ام (مخفف drag & drop interfaces). البته namespace ها در جاوا اسکریپت وجود ندارند و مخصوص تایپ اسکریپت هستند بنابراین در زمان کامپایل شدن کدها به اشیاء خاصی تبدیل می شوند. این مسئله را جهت اطلاع شما گفتم و لازم نیست کار خاصی را برای آن انجام بدهید.
مشکل جدید ما این است که در حال حاضر interface های ما در فایل های دیگر در دسترس نیستند. برای حل این مشکل باید این دو interface را export کنیم:
// Drag & Drop Interfaces namespace DDInterfaces { 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 درون فایل app.ts باید سه علامت اسلش اضافه کرده و تگ بسته ای به نام reference را تعریف کنیم. سپس در path آدرس فایل خود را به آن می دهیم:
/// <reference path="drag-drop-interfaces.ts" /> // Project Type enum ProjectStatus { Active, Finished } // بقیه کدها //
حالا به مشکل جدیدی برمی خوریم. کدهای یک فایل زمانی می توانند از کدهای درون یک namespace استفاده کنند که خودشان هم درون یک namespace با همان نام باشند. مثلا من نام namespace خودم را تغییر داده و app می گذارم:
// 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; } }
سپس به فایل app.ts برمی گردم و یک namespace به همین نام در این فایل ایجاد می کنم و تمام کدهایم را درون آن قرار می دهم:
/// <reference path="drag-drop-interfaces.ts" /> namespace App { // Project Type enum ProjectStatus { Active, Finished } // بقیه کدها //
البته حالا به خطاهایی می خوریم که از prjInput و ... استفاده نمی کنیم. یعنی کدهای زیر در انتهای app.ts:
const prjInput = new ProjectInput(); const activePrjList = new ProjectList('active'); const finishedPrjList = new ProjectList('finished');
این خطا منطقی است بنابراین می گوییم:
// بقیه کدها // new ProjectInput(); new ProjectList('active'); new ProjectList('finished'); }
در حال حاضر اگر کدهای خود را کامپایل کنید، به جای یک فایل دو فایل دریافت می کنیم. همچنین اگر همینطور ادامه بدهید و کدهای خود را به قسمت های مختلفی تقسیم کنید باز هم در تایپ اسکریپت به مشکل برنمی خورید. مشکل اینجاست که اگر کدهای کامپایل شده را در مرورگر تست کنید، برنامه ما به خطا می خورد. همانطور که گفتم namespace ها فقط در تایپ اسکریپت حضور دارند و جاوا اسکریپت متوجه آن نمی شود. برای حل این مشکل به فایل tsconfig.json بروید و outfile را از حالت کامنت خارج کنید:
"sourceMap": true /* Generates corresponding '.map' file. */, "outFile": "./dist/bundle.js", /* Concatenate and emit output to single file. */ "outDir": "./dist" /* Redirect output structure to the directory. */,
من آدرس dist/bundle.js را به outfile داده ام یعنی تمام پروژه من را درون فایلی به نام bundle.js کامپایل کن (فقط یک فایل) و آن را درون پوشه dist قرار بده. البته با این کار خطایی در قسمت ماژول دریافت می کنیم. به دلایل پیچیده و تاریخی باید به جای commonjs از amd استفاده کنیم. اگر با ماژول های جاوا اسکریپت آشنایی ندارید می توانید به این مقاله در سایت مدیوم مراجعه کنید اما واقعا نیازی به این اطلاعات ندارید. همینکه بدانید باید به جای commonjs از amd استفاده کنید، کافی می باشد:
"module": "amd" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
حالا تمام کدهای ما درون یک فایل bundle.js کامپایل می شود بنابراین باید در فایل index.html خود آدرس این فایل را به تگ script بدهیم. من تمام پروژه فصل قبل را برای شما در فایل های مختلف تقسیم کرده ام تا ببینید به چه شکلی در آمده است. در این فایل باید به این مسئله توجه داشته باشید که فقط عناصر مورد نیاز را export کنید.
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.