راهنمای راه اندازی اکسپرس و تایپ اسکریپت – به زبان ساده


اغلب توسعهدهندگان به سهولت استفاده و توسعه سریع NodeJS به همراه وبسرور اکسپرس علاقهمند هستند، اما در مورد مقیاسپذیری و «امنیت نوع» (type-safety) مورد نیاز برای اپلیکیشنهای بزرگ دغدغه دارند. اما جای نگرانی نیست زیرا تایپاسکریپت به کمک شما میآید. در این شرایط همچنان از مزیت یک زبان اسکریپتنویسی بهرهمند هستید و همزمان از پایداری یک زبان استاتیک مانند سی شارپ یا جاوا نیز استفاده میکنید. یادگیری تایپاسکریپت در صورتی که قبلاً با جاوا اسکریپت آشنا باشید کار آسانی است و پیکربندی آن تنها به یک گام اضافی نیاز دارد. باید اشاره کنیم که مقالاتی وجود دارند که شیوه استفاده از اکسپرس و تایپ اسکریپت را نمایش میدهند، اما این مقالات یا زمان زیادی را صرف صحبت در مورد دلیل استفاده از تایپاسکریپت میکنند و یا روی راهاندازی اکسپرس به روشی شیءگرا تأکید ندارند. نقطه تمرکز این مقاله نمایش بهترین و سادهترین پیکربندی برای تایپاسکریپت جهت توسعه NodeJs/Express است.
راهاندازی تایپ اسکریپت
ما در زمان توسعه میتوانیم کد تایپ اسکریپت خودمان را مستقیماً از فایلهای ts. که ایجاد کردهایم اجرا کنیم. با این حال در فاز پروداکشن باید آنها را به جاوا اسکریپت transile کنیم تا سرور ما بتواند مستقیماً از NodeJS اجرا کند. برای پیکربندی شیوه transpile شدن کد تایپاسکریپت و برای تعیین قواعد استایلبندی کد باید به ترتیب فایلهای tsconfig.json و tslint.json را ایجاد کنیم. استفاده از tslint الزامی نیست، اما برای اجرای دقیق استانداردهای کدنویسی بسیار کارآمد است و منجر به تولید کد تمیزتری در بلندمدت میشود.
یک پوشه جدید برای پروژهتان بسازید و در ریشه آن tsconfig.json را با محتوای زیر اضافه کنید:
1{
2 "compilerOptions": {
3 "module": "commonjs",
4 "strict": true,
5 "baseUrl": "./",
6 "outDir": "build",
7 "removeComments": true,
8 "experimentalDecorators": true,
9 "target": "es6",
10 "emitDecoratorMetadata": true,
11 "moduleResolution": "node",
12 "importHelpers": true,
13 "types": [
14 "node"
15 ],
16 "typeRoots": [
17 "node_modules/@types"
18 ]
19 },
20 "include": [
21 "./src/**/*.ts"
22 ],
23 "exclude": [
24 "./src/public/"
25 ]
26}
به گزینه exclude در خط 23 توجه کنید که /src/public/ را نشان میدهد. ما قصد نداریم در این راهنما به بررسی بخش فرانتاند بپردازیم، اما زمانی که خواستید محتوای فرانتاند را نیز اضافه کنید، میتوانید در اینجا انجام دهید.
اکنون باید کد زیر را به فایل tslint.json اضافه کنیم. ما از تنظیمات پیشنهادی با چند تغییر کوچک استفاده میکنیم. شما میتوانید در صورت نیاز هر کدام از این تنظیمات را تغییر دهید.
1{
2 "extends": "tslint:recommended",
3 "rules": {
4 "max-line-length": {
5 "options": [100]
6 },
7 "member-ordering": false,
8 "no-consecutive-blank-lines": false,
9 "object-literal-sort-keys": false,
10 "ordered-imports": false,
11 "quotemark": [true, "single"],
12 "variable-name": [true, "allow-leading-underscore"]
13 }
14}
برای این که بتوانیم کدی را اجرا کنیم باید یک اسکریپت آغازین ایجاد کنیم که سرور ما را بوت کند. از آنجا که هنوز سروری نداریم فعلاً از آن میخواهیم که صرفاً عبارت "hello world" را نمایش دهد. پوشه و فایل src/start.ts را ایجاد کرده و دو خط کد زیر را به آن اضافه کنید:
1// tslint:disable-next-line
2console.log('hello world');
نکته: tslint غیرفعال شده است، زیرا ما را ملزم میکند که از ()console.log استفاده نکنیم و رها کردن آن در این وضعیت در فاز پروداکشن کار خوبی محسوب نمیشود.
در سوی دیگر نمیخواهیم زمانی که کدی را تغییر دادیم، مجبور باشیم همه چیز را به صورت دستی ریاستارت کنیم، بنابراین از nodemon برای رصد تغییرات در فایلهای خود استفاده میکنیم و بدین ترتیب اسکریپت آغازین خود را مجدداً اجرا میکنیم.
1{
2 "watch": ["src"],
3 "ext": "ts",
4 "ignore": ["src/public"],
5 "exec": "NODE_ENV=development ts-node src/start.ts"
6}
اینک ما همه مواردی که برای آغاز توسعه به زبان تایپاسکریپت نیاز داشتیم گرد هم آوردهایم، کافی است وابستگیها را نصب کنیم. اگر هنوز دستور زیر را اجرا نکردهاید، آن را هم اینک اجرا کنید:
npm init
بدین ترتیب پروژه شما به یک پکیج npm تبدیل میشود و سپس میتوانید کتابخانههای npm زیر را نصب کنید:
npm i -D ts-node nodemon typescript tslint
بنابراین اکنون میتوانیم موارد مختلف را با سهولت بیشتر کدنویسی بکنیم و دیگر لازم نیست هر بار دستهای از دستورهای طولانی در کنسول وارد کنیم. یک اسکریپت به package.json اضافه میکنیم تا اسکریپت آغازین را از طریق nodemon و با ts-node اجرا کند.
1{
2 "name": "expresstypescript",
3 "version": "1.0.0",
4 "description": "Develop and ExpressJS webserver using TypeScript",
5 "main": "build/start.js",
6 "scripts": {
7 "test": "none",
8 "start-dev": "nodemon --config \"./util/nodemon.json\"/",
اکنون اگر دستور npm run start-dev را اجرا کنید، باید خروجی hello world را در کنسول مشاهده کنید.
راهاندازی اکسپرس
اکنون که تایپاسکریپت آماده شده و به خوبی اجرا میشود، نوبت آن رسیده که یک وبسرور ساده ExpressJS و چند مسیر ایجاد کنیم. ما میتوانستیم مستقیماً از ExpressJS استفاده کنیم، اما در این صورت از مزیت تایپاسکریپت بهرهمند نمیشدیم. بهتر است که کلاسهایی را با متدها بسازیم، تا این که مجبور باشیم چیزی مانند عبارت زیر را وارد کنیم و آن را بارها و بارها تکرار کنیم:
1let router = express.Router(), router.get/put/post, app.use(router)
برای این که به الگوی MVC وفادار مانده و از برنامهنویسی به سبک شیءگرا استفاده کنید، پیشنهاد میکنیم از OvernightJS بهره بگیرید تا کنترلرها و دکوراتورهای مسیر را به اکسپرس اضافه کنید. شاید بگویید فریمورکهایی مانند NestJS و ts-express-decorators وجود دارند که مسیرهای اکسپرس را دکوراته میکنند، اما همه اینها فریمورکهای بزرگی هستند که وبسایتهای کاملی به مستندات آنها اختصاص یافته است. Overnight (+) صرفاً یک مجموعه کوچک و سادهای از کتابخانهها است که برای افزودن دکوراتورها به اکسپرس و چند چیز دیگر کاربرد دارد. بدین ترتیب یک لایه تجرید روی اکسپرس ایجاد نمیکند و در صورتی که از قبل با اکسپرس آشنا باشید، میتوانید آن را در حدود 10 دقیقه بیاموزید.
در ادامه اکسپرس و Overnight را نصب کرده و یک وبسرور را راهاندازی میکنیم:
npm i -s express body-parser @overnightjs/core @overnightjs/logger npm i -D @types/node @types/express
پکیج body-parser نیز به منظور فراهم ساختن امکان ارسال دادهها به صورت JSON استفاده میشود.
در دایرکتوری src/ یک فایل برای سرور مثلاً به نام ExampleServer.ts ایجاد کرده و یک کلاس با همان نام ایجاد کنید. سپس پوشه/فایل controllers/ExampleController.ts را اضافه کنید. ما ابتدا کنترلر را پیادهسازی کرده و سپس آن را در فایل سرور خود ایمپورت میکنیم.
محتوای زیر را به فایل کنترلر اضافه کنید:
1import { Request, Response } from 'express';
2import { Controller, Middleware, Get, Put, Post, Delete } from '@overnightjs/core';
3import { Logger } from '@overnightjs/logger';
4
5@Controller('api')
6export class ExampleController {
7
8 @Get(':msg')
9 private getMessage(req: Request, res: Response) {
10 Logger.Info(req.params.msg);
11 res.status(200).json({
12 message: req.params.msg,
13 });
14 }
15
16 @Put(':msg')
17 private putMessage(req: Request, res: Response) {
18 Logger.Info(req.params.msg);
19 return res.status(400).json({
20 error: req.params.msg,
21 });
22 }
23
24 @Post(':msg')
25 private postMessage(req: Request, res: Response) {
26 Logger.Info(req.params.msg);
27 return res.status(400).json({
28 error: req.params.msg,
29 });
30 }
31
32 @Delete(':msg')
33 private delMessage(req: Request, res: Response) {
34 try {
35 throw new Error(req.params.msg);
36 } catch (err) {
37 Logger.Err(err, true);
38 return res.status(400).json({
39 error: req.params.msg,
40 });
41 }
42 }
43}
توجه کنید که ما یک متد برای هر مسیر ایجاد کردیم تا همه آنها را در عمل ببینیم. کلاس Logger نیز کارآمد است، زیرا میتواند برای پرینت در یک فایل یا در کنسول استفاده شود، همچنین میتواند کلاً خاموش شود یا بسته به محیط سرور کار خاصی انجام دهد.
زمانی که کار شما با کنترلر به پایان رسید، باید مطمئن شوید که فایل index.ts را با خط زیر به controllers/ اضافه کردهاید:
1export * from ‘./ExampleController’;
به این ترتیب فایلهای کنترلر جدید ایجاد شده در آینده میتوانند به سادگی صرفاً با افزودن یک خط کد اضافه شوند.
در سرور کنترلرها را ایمپورت کرده و کلاس را با اکسپورت Server مربوط به Overnight بسط دهید. با بسط دادن Server به وهلهای از اکسپرس با this.app دسترسی مییابید که میتوانید با آن دقیقاً همانند هر وهله نرمال دیگر اکسپرس که با دستور زیر ساخته شده است تعامل پیدا کنید:
1require(‘express’)()
کنترلرها باید وهلهسازی شده و به صورت مدخلی به (…)super.addControllers اضافه شوند تا مسیرهایتان فعال شوند. مطمئن شوید که کنترلهایتان را پس از تنظیم میانافزار اما قبل از آغاز به کار سرور اضافه کردهاید.
1import * as bodyParser from 'body-parser';
2import * as controllers from './controllers';
3import { Server } from '@overnightjs/core';
4import { Logger } from '@overnightjs/logger';
5
6class ExampleServer extends Server {
7
8 private readonly SERVER_STARTED = 'Example server started on port: ';
9
10 constructor() {
11 super(true);
12 this.app.use(bodyParser.json());
13 this.app.use(bodyParser.urlencoded({extended: true}));
14 this.setupControllers();
15 }
16
17 private setupControllers(): void {
18 const ctlrInstances = [];
19 for (const name in controllers) {
20 if (controllers.hasOwnProperty(name)) {
21 const controller = (controllers as any)[name];
22 ctlrInstances.push(new controller());
23 }
24 }
25 super.addControllers(ctlrInstances);
26 }
27
28 public start(port: number): void {
29 this.app.get('*', (req, res) => {
30 res.send(this.SERVER_STARTED + port);
31 });
32 this.app.listen(port, () => {
33 Logger.Imp(this.SERVER_STARTED + port);
34 });
35 }
36}
37
38export default ExampleServer;
اکنون که سرور و کنترلرهای خود را در اختیار داریم، باید همه چیز را از اسکریپت آغازین بوت کنیم. به این منظور سرور را ایمپورت، آن را وهلهسازی و سپس start(portNumber) را فراخوانی کنید:
1import ExampleServer from './ExampleServer';
2
3const exampleServer = new ExampleServer();
4exampleServer.start(3000);
زمانی که دیدید عبارت زیر در کنسول نمایش یافته است:
1"[someTimestamp]: Example server started on port: 3000"
میتوانید یک ابزار فراخوانی API (مانند Postman) را باز کرده و درخواستهایی به سرور ارسال کنید. اگر از دستورهای این راهنما به طور کامل پیروی کرده باشید، اینک باید ببینید که بخش msg: مسیرها در کنسول نمایش مییابند.
کدنویسی
اکنون که یک سرور توسعه کاملاً عملیاتی را راهاندازی و اجرا کردهایم، تنها چیزی که نیاز داریم این است که آن را برای پروداکشن آماده کنیم. در حالتی که فایلهای ts. را در زمان توسعه حذف کرده باشید باید هر بار که traspile میکنید، پوشه build/ را پاک کنید، چون در غیر این صورت با فایلهای ts. باطلی رو به رو میشوید.
برای آغاز کدنویسی پروداکشن باید به جای src/start.ts دستور build/start.js را اجرا کنید. در ادامه دو مسیر دیگر به package.json اضافه میکنیم تا کد پروداکشن را ساخته و اجرا کنیم. دستور tsc کد ما را transpile میکند:
1{
2 "name": "expresstypescript",
3 "version": "1.0.0",
4 "description": "Develop and ExpressJS webserver using TypeScript",
5 "main": "build/start.js",
6 "scripts": {
7 "test": "none",
8 "start-dev": "nodemon --config \"./util/nodemon.json\"/",
9 "build": "rm -rf ./build/ && tsc",
10 "start": "node build/start.js"
11 },
12 "repository": {
13 "type": "git",
14 "url": "git+https://github.com/seanpmaxwell/ExpressTypeScript.git"
15 },
زمانی که سرور آغاز شد، همه مسیرها باید دقیقاً همانند قبل عمل کنند. بدین ترتیب به پایان این راهنما با موضوع راهاندازی اکسپرس و تایپاسکریپت میرسیم.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- آموزش راه اندازی و اجرای Express ،Node.js و MongoDB — راهنمای گام به گام
- راهنمای جامع تایپ اسکریپت (Typescript) — از صفر تا صد
- قابلیت های کمتر شناخته شده TypeScript — راهنمای کاربردی
==