ترکیب Express و Typescript: نوشتن اولین سرور

Combining Typescript and Express: The First Server

01 شهریور 1399
ترکیب Express و Typescript: نوشتن اولین سرور – قسمت 75

ما در قسمت قبل موارد اولیه برای راه اندازی پروژه را نصب و ساماندهی کردیم و حالا نوبت به کدنویسی است. من می خواهم یک برنامه REST API بسیار ساده را ایجاد کنم اما شما می توانید هر برنامه دیگری را که دوست دارید با استفاده از node و express و تایپ اسکریپت پیاده سازی کنید. در قدم اول در پوشه src فایلی به نام app.ts ایجاد می کنم.

همانطور که می دانید در express برای راه اندازی یک سرور مجازی می توانیم به شکل زیر عمل کنیم:

const express = require('express');

const app = express();

app.listen(3000);

یعنی ابتدا express را به فایل خودمان import کرده و سپس آن را مانند یک تابع اجرا کنیم. در نهایت با دستور listen به Express می گوییم که port خاصی را زیر نظر بگیرد، مثلا در کد بالا 3000. با نوشتن کد بالا خطایی را در رابطه با require دریافت می کنید. تابع require در زبان node.js یک تابع عادی است اما ربطی به مرورگر ندارد و مرورگر ها با آن آشنا نیستند بنابراین تایپ اسکریپت به شما خطا می دهد. ما در قسمت lib در فایل tsconfig.json از هیچ کتابخانه ای استفاده نکرده ایم که با استفاده از آن از node.js پشتیبانی کنیم. به همین دلیل تایپ اسکریپت با تابع require آشنا نیست و به ما خطا می دهد. برای حل این مشکل باید types را برای زبان node نصب کنیم. در پنجره ترمینال خود در این پروژه کد زیر را اجرا نمایید:

npm install --save-dev @types/node

این کد مربوط به تایپ های زبان node در جاوا اسکریپت است:

https://www.npmjs.com/package/@types/node

ما در فصل های قبلی با نصب انواع تایپ های custom آشنا شده ایم بنابراین دوباره در این مورد توضیح نمی دهم. با اجرای کد بالا و نصب پکیج types/node خطای مربوط به require از بین می رود اما هنوز مشکلی وجود دارد. اگر موس خود را روی متغیر app ببرید (که حاوی express است) تایپ اسکریپت نمی تواند تشخیص بدهد که درون app چه چیزی وجود دارد. چرا؟ به دلیل اینکه با نصب پکیج types/node به تایپ اسکریپت یاد داده ایم که چطور با زبان node.js برخورد کند اما هنوز چیزی در مورد express.js نگفته ایم بنابراین باید پکیج زیر را نیز نصب کنید:

npm install --save-dev @types/express

این کد مربوط به این صفحه است:

https://www.npmjs.com/package/@types/express

حالا که هر دو تایپ خاص node.js و express.js را نصب کرده ایم آیا خطای ما از بین می رود؟ آیا اگر حالا موس را روی app ببریم، تایپ آن نمایش داده می شود؟ خیر! هنوز هم مشکلی وجود دارد! دلیل این مشکل، نحوه import کردن Express است. syntax ما از نوع commonJS است که به صورت پیش فرض در زبان Node.js استفاده می شود اما ما می توانیم از syntax مربوط به ES Modules استفاده کنیم که در مرورگر ها کاربرد دارد:

import express from 'express';

const app = express();

app.listen(3000);

حالا اگر موس خود را روی app ببرید به شما می گوید که تایپ app از نوع express است.

یادتان باشد که استفاده از این نوع از دستور import به صورت آزمایشی در Node.js وجود دارد (زمان بسیار طولانی است که در همان حالت آزمایشی یا experimental flag باقی مانده است) اما هیچ برنامه نویس node.js ای از چنین دستوری برای وارد کردن پکیج ها استفاده نمی کند چرا که پر ریسک و آزمایشی است بنابراین نمی توان به آن اعتماد کرد. حتما می پرسید پس چرا ما چنین کاری می کنیم؟ ما از این syntax استفاده نمی کنیم! یادتان باشد که ما در حال کدنویسی در app.ts هستیم بنابراین کدهای ما تایپ اسکریپت هستند نه جاوا اسکریپت! و زمانی که کدهایمان را کامپایل کنیم، دستور import بالا به همان دستور require در node تبدیل می شود. ما این مسئله را در فایل tsconfig.json تعیین کرده بودیم:

    "moduleResolution": "node",                   /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */

برای تست این موضوع می توانید دستور tsc -w را در ترمینال خود اجرا کنید تا وارد watch mode بشویم. سپس فایل را ذخیره کنید تا کامپایل شود. کدهای کامپایل شده ما در فایلی به نام app.js در پوشه ای به نام dist قرار می گیرد (در فایل tsconfig.json این موضوع را کدنویسی کرده بودیم که outDir و rootDir چه آدرس هایی داشته باشند) و کدهایش به شکل زیر هستند:

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const app = express_1.default();
app.listen(3000);

همانطور که مشاهده می کنید، دستورات نوشته شده در app.js کاملا متفاوت هستند و همچنین در اینجا از require استفاده کرده ایم نه import ساده.

ما هر زمان که کدهای تایپ اسکریپت را کامپایل کنیم، فایل app.js تغییر خواهد کرد و برای اعمال شدن تغییرات باید سرور مجازی خود را ریستارت کنیم. اگر یادتان باشد در جلسه قبل پکیجی به نام nodemon (تفلظ: نود-مان) را نصب کرده بودیم که مسئول همین کار بود. بنابراین باید یک ترمینال جدید را باز کنید (ترمینال قبلی را نبندید تا از Watch mode خارج نشویم) تا دستور اجرای آن را بدهیم. برای این کار ابتدا وارد package.json بشوید و یک اسکریپت جدید را برایش تعریف کنید:

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon dist/app.js"
  },

با این کار nodemon فایل app.js درون پوشه dist را اجرا خواهد کرد. فایل package.json را ذخیره کرده و npm start را در پنجره جدید ترمینال اجرا کنید. با اجرای این دستور سرور ما اجرا می شود اما فعلا هیچ کاری نمی کند. در قسمت بعد اولین route خود را خواهیم نوشت و با middleware ها کار خواهیم کرد.

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

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

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