[[:oktatas:web:back-end_framework:express|< Express]] ====== Express - TypeScript ====== * **Szerző:** Sallai András * Copyright (c) 2023, Sallai András * Szerkesztve: 2023, 2024 * Licenc: [[https://creativecommons.org/licenses/by-sa/4.0/|CC Attribution-Share Alike 4.0 International]] * Web: https://szit.hu ===== Projekt ===== 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. ===== Függőségek ===== 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 ===== tsconfig.json ===== 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 } } ==== esModuleInterop ==== 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'; ==== forceConsistentCasingInFileNames ==== 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 } } ==== include ==== 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"] } ===== package.json ===== 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" } } ==== ts-node és nodemon használata ==== 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. ==== ts-node-dev használata ==== 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" } } * --respawn - Indítsuk újra a folyamatot ha változik a könyvtár. * --transpile-only - A TypeScript ellenőrzése, típushibák figyelése nélkül. 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. ===== Szerver ===== 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 ===== Router külön fájlba ===== 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;