Az Express API projektet elkészíthetjük TypeScript nyelven is.
A projekt elkészítése:
mkdir app01 cd app01 npm init -y
A következő kezdeti könyvtárszerkezetet fogjuk használni:
app01/ |-app/ | `-index.js |-node_modules/ |-src/ | `-index.ts |-package-lock.json |-package.json `-tsconfig.json
A forráskódot az src könyvtárban írjuk. A TypeScript fordító az app könyvtárba dolgozik.
Az express-re továbbra is szükségünk van:
npm install express
Szükségünk van néhány plusz függőségre, fejlesztési időben:
npm install typescript @types/node @types/express --save-dev
A TypeScript fordító számára célszerű megadni néhány információt. Itt egy egyszerű tsconfig.json fájlt láthatunk:
{ "compilerOptions": { "target": "ES6", "module": "commonjs", "outDir": "./app", "strict": true, "esModuleInterop": true } }
Az esModuleInterop beállítás szükséges a ES6 és CommonJS modulok együttműködéséhez. Nélküle, például az express import csak így hajtható végre:
import * as express from 'express';
Ha true értékre van állítva használhatjuk így:
import express from 'express';
Ez a beállítás nincs a fenti mintabeállításokban, de jól jöhet.
A forceConsistentCasingInFileNames ha true értékre van állítva, a fordító az importálásoknál megköveteli a kis- és nagybetűk egyezésének vizsgálatát. Így kompatibilis lesz a kódunk olyan rendszerekkel is, ahol a kis- és nagybetűs fájlnevek mást jelenthetnek.
{ "compilerOptions": { "forceConsistentCasingInFileNames": true } }
Megadhatjuk, hogy az csak src könyvtárban keresse a .ts fájlokat:
{ "include": ["src/**/*.ts"], }
Alapértelmezetten, minden mappában keres .ts fájt, kivéve a node_modules.
Van aki kifejezetten kizárja a node_modules használatát, de ez csak az egyértelműsítést szolgálja.
{ "include": ["src/**/*.ts"], "exclude": ["node_modules"] }
A package.json fájlban írjunk egy start és egy build scriptet:
{ "name": "express-typescript", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node app/index.js", "build": "tsc" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@types/express": "^4.17.17", "@types/node": "^20.3.1", "typescript": "^5.1.3" }, "dependencies": { "express": "^4.18.2" } }
A ts-node nem kötelező elem, de segítheti a TypeScript értelmezését JavaScript-re fordítás nélkül. A ts-node nem fordít az app könyvtárba, csak értelmezi a TypeScripte, és úgy futtatja.
A ts-node csak egyetlen állomány képes figyelni, ezért ebben a leírásban nodemon-nal együtt fogjuk használni.
Legyen telepítve a ts-node és a nodemon csomag:
npm install --save-dev ts-node nodemon
Készítsünk a nodemon számára beállítófájlt nodemon.json néven:
{ "watch": [ "src" ], "ext": "ts", "exec": "ts-node src/index.ts" }
A package.json scripts része ezek után:
{ "scripts": { "dev": "nodemon", "build": "tsc", "start": "node app" } }
Ha az npm run dev paranccsal indítjuk a szervert, akkor fordítás nélkül futni fog a TypeScript kódunk.
A fejlesztés indítása:
npm run dev
Tudunk fejleszteni, a mentéskor azonnal látjuk a változtatásokat.
Ha szeretnénk az app könyvtárba legyártani a kész terméket futtatnunk kell build feladatot.
npm run build
A kész termék futtatása ezek után:
npm start
Az npm start az app könyvtárból indítja az alkalmazást.
A ts-node-dev értelmező és figyelő egyben. Figyeli az adott könyvtár változásait, mint a nodemon, de egyben értelmezi is a TypeScriptet.
Telepítés:
npm install ts-node-dev
A ts-node-dev kiváltja a ts-node és a nodemon feladatait.
A package.json scripts része ezek után:
{ "scripts": { "dev": "ts-node-dev --respawn --transpile-only src/index.ts", "build": "tsc", "start": "node app" } }
A --transpile-only kapcsoló akkor lehet hasznos, ha gyorsan látni akarjuk a változásokat. A típushibák viszont csak később kerülnek a felszínre, ezért óvatosan használjuk.
Az express csomagból most szükségünk lesz három típusra. Az Application, a Request és a Response szökséges.
import express, { Application, Request, Response } from 'express'; const app: Application = express(); const PORT = 8000; app.get('/msg', (req: Request, res: Response) => { res.json({ message: 'Helló'}); }); app.listen(PORT, () => { console.log(`Running: localhost:${PORT}`); });
Az Application típus használata elhagyható, mivel az app objektum azonnal értéket kap. A req objektum Request és a res objektum Response használata azonban kötelező.
Használjuk a dev feladatot a teszteléshez:
Indítás:
npm run dev
Nagyobb projekteknél a routingot külön fájlba szokás tenni. Az index.ts fájlban csak importáljuk, majd az alkalmazáshoz adjuk mint egy köztes szoftvert.
import express, { Application, Request, Response } from 'express'; import router from './routes/api'; const app: Application = express(); const PORT = 8000; app.use(router) app.listen(PORT, () => { console.log(`Running: localhost:${PORT}`); });
import { Router, Request, Response } from 'express'; const router: Router = Router(); router.get('/msg', (req: Request, res: Response) => { res.json({ message: 'Helló'}); }); export default router;