Sužinokite, kaip sukurti patikimą serverio pusės tipų saugumą naudojant TypeScript ir Node.js. Praktiniai pavyzdžiai, geriausios praktikos ir pažangios technikos.
TypeScript Node.js: Tipų saugumo įgyvendinimas serverio pusėje
Nuolat besivystančiame žiniatinklio kūrimo pasaulyje, tvirtų ir lengvai prižiūrimų serverio pusės aplikacijų kūrimas yra itin svarbus. Nors JavaScript ilgą laiką buvo žiniatinklio kalba, jos dinamiškumas kartais gali sukelti vykdymo laiko klaidas ir sunkumus plečiant didesnius projektus. TypeScript, JavaScript supersetas, kuris prideda statinį tipavimą, siūlo galingą sprendimą šiems iššūkiams. Derinant TypeScript su Node.js, sukuriama patraukli aplinka tipų saugių, plečiamų ir lengvai prižiūrimų backend sistemų kūrimui.
Kodėl TypeScript Node.js serverio pusės kūrimui?
TypeScript suteikia daugybę privalumų Node.js kūrimui, sprendžiant daugelį apribojimų, būdingų dinamiškam JavaScript tipavimui.
- Patobulintas tipų saugumas: TypeScript įdiegia griežtą tipų tikrinimą kompiliavimo metu, aptikdama galimas klaidas dar prieš joms pasiekiant produkciją. Tai sumažina vykdymo laiko išimčių riziką ir pagerina bendrą jūsų aplikacijos stabilumą. Įsivaizduokite scenarijų, kai jūsų API tikisi vartotojo ID kaip skaičiaus, bet gauna eilutę. TypeScript pažymėtų šią klaidą kūrimo metu, užkertant kelią galimam strigimui produkcijoje.
- Geresnis kodo palaikomumas: Tipų anotacijos palengvina kodo supratimą ir refaktorinimą. Dirbant komandoje, aiškios tipų apibrėžtys padeda kūrėjams greitai suvokti skirtingų kodo dalių paskirtį ir numatomą elgesį. Tai ypač svarbu ilgalaikiams projektams su besikeičiančiais reikalavimais.
- Patobulintas IDE palaikymas: TypeScript statinis tipavimas leidžia IDE (integruotoms kūrimo aplinkoms) teikti geresnį automatinį užbaigimą, kodo naršymą ir refaktorinimo įrankius. Tai žymiai pagerina kūrėjų produktyvumą ir sumažina klaidų tikimybę. Pavyzdžiui, VS Code TypeScript integracija siūlo išmanius pasiūlymus ir klaidų paryškinimą, todėl kūrimas tampa greitesnis ir efektyvesnis.
- Ankstyvas klaidų aptikimas: Nustatydamas su tipais susijusias klaidas kompiliavimo metu, TypeScript leidžia jums išspręsti problemas ankstyvame kūrimo cikle, taupant laiką ir mažinant derinimo pastangas. Šis aktyvus požiūris neleidžia klaidoms plisti per aplikaciją ir paveikti vartotojų.
- Laipsniškas diegimas: TypeScript yra JavaScript supersetas, o tai reiškia, kad esamas JavaScript kodas gali būti laipsniškai perkeliamas į TypeScript. Tai leidžia palaipsniui įdiegti tipų saugumą, nereikalaujant visiškai perrašyti kodo bazės.
TypeScript Node.js projekto nustatymas
Norėdami pradėti naudoti TypeScript ir Node.js, turėsite įdiegti Node.js ir npm (Node Package Manager). Įdiegę, galite atlikti šiuos veiksmus, kad nustatytumėte naują projektą:
- Sukurkite projekto katalogą: Sukurkite naują katalogą savo projektui ir terminale pereikite į jį.
- Inicijuokite Node.js projektą: Paleiskite
npm init -y, kad sukurtumėtepackage.jsonfailą. - Įdiekite TypeScript: Paleiskite
npm install --save-dev typescript @types/node, kad įdiegtumėte TypeScript ir Node.js tipų apibrėžtis. Paketas@types/nodesuteikia tipų apibrėžtis Node.js įmontuotiems moduliams, leidžiant TypeScript suprasti ir patvirtinti jūsų Node.js kodą. - Sukurkite TypeScript konfigūracijos failą: Paleiskite
npx tsc --init, kad sukurtumėtetsconfig.jsonfailą. Šis failas konfigūruoja TypeScript kompiliatorių ir nurodo kompiliavimo parinktis. - Konfigūruokite tsconfig.json: Atidarykite
tsconfig.jsonfailą ir sukonfigūruokite jį pagal savo projekto poreikius. Kai kurios dažnos parinktys apima: target: Nurodo ECMAScript tikslinę versiją (pvz., "es2020", "esnext").module: Nurodo naudojamą modulio sistemą (pvz., "commonjs", "esnext").outDir: Nurodo išvesties katalogą kompiliuotiems JavaScript failams.rootDir: Nurodo šakninį katalogą TypeScript šaltinio failams.sourceMap: Įgalina šaltinio žemėlapio generavimą lengvesniam derinimo procesui.strict: Įgalina griežtą tipų tikrinimą.esModuleInterop: Įgalina CommonJS ir ES modulių sąveiką.
Pavyzdinis tsconfig.json failas gali atrodyti taip:
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": [
"src/**/*"
]
}
Ši konfigūracija nurodo TypeScript kompiliatoriui kompiliuoti visus .ts failus kataloge src, išvesti sukompiliuotus JavaScript failus į katalogą dist ir generuoti šaltinio žemėlapius derinimo procesui.
Pagrindinės tipų anotacijos ir sąsajos
TypeScript pristato tipų anotacijas, kurios leidžia aiškiai nurodyti kintamųjų, funkcijų parametrų ir grąžinamų reikšmių tipus. Tai leidžia TypeScript kompiliatoriui atlikti tipų tikrinimą ir anksti aptikti klaidas.
Pagrindiniai tipai
TypeScript palaiko šiuos pagrindinius tipus:
string: Atspindi teksto reikšmes.number: Atspindi skaitines reikšmes.boolean: Atspindi bulio (loginės) reikšmes (truearbafalse).null: Atspindi tyčinį reikšmės nebuvimą.undefined: Atspindi kintamąjį, kuriam nebuvo priskirta reikšmė.symbol: Atspindi unikalią ir nekeičiamą reikšmę.bigint: Atspindi sveikąsias reikšmes su savavališku tikslumu.any: Atspindi bet kokio tipo reikšmę (naudokite retai).unknown: Atspindi reikšmę, kurios tipas nežinomas (saugesnis neiany).void: Atspindi grąžinamos reikšmės nebuvimą iš funkcijos.never: Atspindi reikšmę, kuri niekada neįvyksta (pvz., funkcija, kuri visada išmeta klaidą).array: Atspindi sutvarkytą to paties tipo reikšmių rinkinį (pvz.,string[],number[]).tuple: Atspindi sutvarkytą reikšmių rinkinį su specifiniais tipais (pvz.,[string, number]).enum: Atspindi vardinių konstantų rinkinį.object: Atspindi neprimityvų tipą.
Štai keletas tipų anotacijų pavyzdžių:
let name: string = "John Doe";
let age: number = 30;
let isStudent: boolean = false;
function greet(name: string): string {
return `Hello, ${name}!`;
}
let numbers: number[] = [1, 2, 3, 4, 5];
let person: { name: string; age: number } = {
name: "Jane Doe",
age: 25,
};
Sąsajos
Sąsajos apibrėžia objekto struktūrą. Jos nurodo savybes ir metodus, kuriuos objektas privalo turėti. Sąsajos yra galingas būdas užtikrinti tipų saugumą ir pagerinti kodo palaikomumą.
Štai sąsajos pavyzdys:
interface User {
id: number;
name: string;
email: string;
isActive: boolean;
}
function getUser(id: number): User {
// ... fetch user data from database
return {
id: 1,
name: "John Doe",
email: "john.doe@example.com",
isActive: true,
};
}
let user: User = getUser(1);
console.log(user.name); // John Doe
Šiame pavyzdyje User sąsaja apibrėžia vartotojo objekto struktūrą. Funkcija getUser grąžina objektą, atitinkantį User sąsają. Jei funkcija grąžina objektą, neatitinkantį sąsajos, TypeScript kompiliatorius išmes klaidą.
Tipų aliasai
Tipų aliasai sukuria naują tipo pavadinimą. Jie nesukuria naujo tipo – jie tiesiog suteikia esamam tipui aprašomesnį ar patogesnį pavadinimą.
type StringOrNumber = string | number;
let value: StringOrNumber = "hello";
value = 123;
//Type alias for a complex object
type Point = {
x: number;
y: number;
};
const myPoint: Point = { x: 10, y: 20 };
Paprastos API kūrimas naudojant TypeScript ir Node.js
Sukurkime paprastą REST API naudodami TypeScript, Node.js ir Express.js.
- Įdiekite Express.js ir jo tipų apibrėžtis:
Paleiskite
npm install express @types/express - Sukurkite failą pavadinimu
src/index.tssu šiuo kodu:
import express, { Request, Response } from 'express';
const app = express();
const port = process.env.PORT || 3000;
interface Product {
id: number;
name: string;
price: number;
}
const products: Product[] = [
{ id: 1, name: 'Laptop', price: 1200 },
{ id: 2, name: 'Keyboard', price: 75 },
{ id: 3, name: 'Mouse', price: 25 },
];
app.get('/products', (req: Request, res: Response) => {
res.json(products);
});
app.get('/products/:id', (req: Request, res: Response) => {
const productId = parseInt(req.params.id);
const product = products.find(p => p.id === productId);
if (product) {
res.json(product);
} else {
res.status(404).json({ message: 'Product not found' });
}
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Šis kodas sukuria paprastą Express.js API su dviem galiniais taškais:
/products: Grąžina produktų sąrašą./products/:id: Grąžina konkretų produktą pagal ID.
Product sąsaja apibrėžia produkto objekto struktūrą. products masyvas yra produktų objektų, atitinkančių Product sąsają, sąrašas.
Norėdami paleisti API, turėsite sukompiliuoti TypeScript kodą ir paleisti Node.js serverį:
- Kompiliuokite TypeScript kodą: Paleiskite
npm run tsc(galbūt reikės apibrėžti šį scenarijųpackage.jsonfaile kaip"tsc": "tsc"). - Paleiskite Node.js serverį: Paleiskite
node dist/index.js.
Tada galite pasiekti API galinius taškus naršyklėje arba naudodami įrankį, pvz., curl:
curl http://localhost:3000/products
curl http://localhost:3000/products/1
Pažangios TypeScript technikos serverio pusės kūrimui
TypeScript siūlo keletą pažangių funkcijų, kurios gali dar labiau pagerinti tipų saugumą ir kodo kokybę serverio pusės kūrimo metu.
Generikai
Generikai leidžia rašyti kodą, kuris gali veikti su skirtingais tipais, nepažeidžiant tipų saugumo. Jie suteikia būdą parametrizuoti tipus, todėl jūsų kodas tampa labiau pakartotinai naudojamas ir lankstesnis.
Štai generinės funkcijos pavyzdys:
function identity<T>(arg: T): T {
return arg;
}
let myString: string = identity<string>("hello");
let myNumber: number = identity<number>(123);
Šiame pavyzdyje identity funkcija priima T tipo argumentą ir grąžina to paties tipo reikšmę. <T> sintaksė rodo, kad T yra tipo parametras. Kai iškviečiate funkciją, galite aiškiai nurodyti T tipą (pvz., identity<string>) arba leisti TypeScript jį nustatyti iš argumento (pvz., identity("hello")).
Diskriminuotos sąjungos
Diskriminuotos sąjungos, dar žinomos kaip žymėtos sąjungos, yra galingas būdas atvaizduoti reikšmes, kurios gali būti vieno iš kelių skirtingų tipų. Jos dažnai naudojamos būsenų automatams modeliuoti arba įvairioms klaidoms atvaizduoti.
Štai diskriminuotos sąjungos pavyzdys:
type Success = {
status: 'success';
data: any;
};
type Error = {
status: 'error';
message: string;
};
type Result = Success | Error;
function handleResult(result: Result) {
if (result.status === 'success') {
console.log('Success:', result.data);
} else {
console.error('Error:', result.message);
}
}
const successResult: Success = { status: 'success', data: { name: 'John Doe' } };
const errorResult: Error = { status: 'error', message: 'Something went wrong' };
handleResult(successResult);
handleResult(errorResult);
Šiame pavyzdyje Result tipas yra diskriminuota Success ir Error tipų sąjunga. status savybė yra diskriminatorius, kuris nurodo, koks yra reikšmės tipas. Funkcija handleResult naudoja diskriminatorių, kad nustatytų, kaip elgtis su reikšme.
Naudingieji tipai
TypeScript teikia keletą integruotų naudingųjų tipų, kurie gali padėti manipuliuoti tipais ir kurti glaustesnį bei išraiškingesnį kodą. Kai kurie dažniausiai naudojami naudingieji tipai apima:
Partial<T>: Padaro visasTsavybes neprivalomomis.Required<T>: Padaro visasTsavybes privalomomis.Readonly<T>: Padaro visasTsavybes tik skaitomomis.Pick<T, K>: Sukuria naują tipą, turintį tik tasTsavybes, kurių raktai yraK.Omit<T, K>: Sukuria naują tipą su visomisTsavybėmis, išskyrus tas, kurių raktai yraK.Record<K, T>: Sukuria naują tipą suKtipo raktais irTtipo reikšmėmis.Exclude<T, U>: Pašalina išTvisus tipus, kurie priskiriamiU.Extract<T, U>: Išskiria išTvisus tipus, kurie priskiriamiU.NonNullable<T>: PašalinanullirundefinedišT.Parameters<T>: Gauna funkcijos tipoTparametrus kaip rinkinį.ReturnType<T>: Gauna funkcijos tipoTgrąžinimo tipą.InstanceType<T>: Gauna konstruktoriaus funkcijos tipoTegzemplioriaus tipą.
Štai keletas pavyzdžių, kaip naudoti naudingųjų tipus:
interface User {
id: number;
name: string;
email: string;
}
// Make all properties of User optional
type PartialUser = Partial<User>;
// Create a type with only the name and email properties of User
type UserInfo = Pick<User, 'name' | 'email'>;
// Create a type with all properties of User except the id
type UserWithoutId = Omit<User, 'id'>;
TypeScript Node.js aplikacijų testavimas
Testavimas yra esminė tvirtų ir patikimų serverio pusės aplikacijų kūrimo dalis. Naudojant TypeScript, galite pasinaudoti tipų sistema, kad parašytumėte efektyvesnius ir lengviau prižiūrimus testus.
Populiarūs Node.js testavimo karkasai apima Jest ir Mocha. Šie karkasai suteikia įvairias funkcijas vienetų testams, integracijos testams ir galutiniams testams rašyti.
Štai vieneto testo pavyzdys naudojant Jest:
// src/utils.ts
export function add(a: number, b: number): number {
return a + b;
}
// test/utils.test.ts
import { add } from '../src/utils';
describe('add', () => {
it('should return the sum of two numbers', () => {
expect(add(1, 2)).toBe(3);
});
it('should handle negative numbers', () => {
expect(add(-1, 2)).toBe(1);
});
});
Šiame pavyzdyje add funkcija testuojama naudojant Jest. describe blokas sugrupuoja susijusius testus. it blokai apibrėžia atskirus testavimo atvejus. expect funkcija naudojama tvirtinimams apie kodo elgesį atlikti.
Rašant testus TypeScript kodui, svarbu užtikrinti, kad jūsų testai apimtų visus galimus tipų scenarijus. Tai apima testavimą su skirtingais įvesties tipais, testavimą su null ir undefined reikšmėmis bei testavimą su neteisingais duomenimis.
Geriausios praktikos TypeScript Node.js kūrimui
Kad jūsų TypeScript Node.js projektai būtų gerai struktūrizuoti, lengvai prižiūrimi ir plečiami, svarbu laikytis kai kurių geriausių praktikų:
- Naudokite griežtą režimą: Įjunkite griežtą režimą savo
tsconfig.jsonfaile, kad įdiegtumėte griežtesnį tipų tikrinimą ir anksti aptiktumėte galimas klaidas. - Apibrėžkite aiškias sąsajas ir tipus: Naudokite sąsajas ir tipus, kad apibrėžtumėte duomenų struktūrą ir užtikrintumėte tipų saugumą visoje savo aplikacijoje.
- Naudokite generikus: Naudokite generikus, kad parašytumėte pakartotinai naudojamą kodą, kuris gali veikti su skirtingais tipais, nepažeidžiant tipų saugumo.
- Naudokite diskriminuotas sąjungas: Naudokite diskriminuotas sąjungas, kad atvaizduotumėte reikšmes, kurios gali būti vieno iš kelių skirtingų tipų.
- Rašykite išsamius testus: Rašykite vienetų testus, integracijos testus ir galutinius testus, kad užtikrintumėte, jog jūsų kodas veikia tinkamai ir jūsų aplikacija yra stabili.
- Laikykitės nuoseklaus kodavimo stiliaus: Naudokite kodo formatavimo įrankį, pvz., Prettier, ir linterį, pvz., ESLint, kad įdiegtumėte nuoseklų kodavimo stilių ir aptiktumėte galimas klaidas. Tai ypač svarbu dirbant komandoje, kad būtų išlaikyta nuosekli kodo bazė. Yra daug ESLint ir Prettier konfigūracijos parinkčių, kurias galima bendrinti visoje komandoje.
- Naudokite priklausomybių injekciją: Priklausomybių injekcija yra dizaino modelis, leidžiantis atskirti kodą ir padaryti jį labiau testuojamu. Įrankiai, tokie kaip InversifyJS, gali padėti įdiegti priklausomybių injekciją jūsų TypeScript Node.js projektuose.
- Įgyvendinkite tinkamą klaidų valdymą: Įdiekite tvirtą klaidų valdymą, kad grakščiai sugautumėte ir apdorotumėte išimtis. Naudokite try-catch blokus ir klaidų registravimą, kad išvengtumėte aplikacijos strigimo ir suteiktumėte naudingos derinimo informacijos.
- Naudokite modulių rišiklį: Naudokite modulių rišiklį, pvz., Webpack ar Parcel, kad sujungtumėte savo kodą ir optimizuotumėte jį gamybai. Nors dažnai siejami su frontend kūrimu, modulių rišikliai gali būti naudingi ir Node.js projektams, ypač dirbant su ES moduliais.
- Apsvarstykite karkaso naudojimą: Išanalizuokite karkasus, tokius kaip NestJS ar AdonisJS, kurie suteikia struktūrą ir konvencijas kuriant plečiamas ir lengvai prižiūrimas Node.js aplikacijas su TypeScript. Šie karkasai dažnai apima tokias funkcijas kaip priklausomybių injekcija, maršrutizavimas ir tarpinės programinės įrangos palaikymas.
Diegimo aspektai
TypeScript Node.js aplikacijos diegimas yra panašus į standartinės Node.js aplikacijos diegimą. Tačiau yra keletas papildomų aspektų:
- Kompiliavimas: Prieš diegdami, turėsite sukompiliuoti savo TypeScript kodą į JavaScript. Tai gali būti atliekama kaip jūsų kūrimo proceso dalis.
- Šaltinio žemėlapiai: Apsvarstykite galimybę įtraukti šaltinio žemėlapius į savo diegimo paketą, kad supaprastintumėte derinimo procesą produkcijoje.
- Aplinkos kintamieji: Naudokite aplinkos kintamuosius, kad sukonfigūruotumėte savo aplikaciją skirtingoms aplinkoms (pvz., kūrimo, testavimo, gamybos). Tai yra standartinė praktika, tačiau tampa dar svarbesnė dirbant su sukompiliuotu kodu.
Populiarios Node.js diegimo platformos apima:
- AWS (Amazon Web Services): Siūlo įvairias paslaugas Node.js aplikacijų diegimui, įskaitant EC2, Elastic Beanstalk ir Lambda.
- Google Cloud Platform (GCP): Teikia panašias paslaugas kaip AWS, įskaitant Compute Engine, App Engine ir Cloud Functions.
- Microsoft Azure: Siūlo paslaugas, tokias kaip Virtualios mašinos, App Service ir Azure Functions, skirtas Node.js aplikacijų diegimui.
- Heroku: Platforma kaip paslauga (PaaS), kuri supaprastina Node.js aplikacijų diegimą ir valdymą.
- DigitalOcean: Teikia virtualius privačius serverius (VPS), kuriuos galite naudoti Node.js aplikacijoms diegti.
- Docker: Konteinerizavimo technologija, leidžianti supakuoti jūsų aplikaciją ir jos priklausomybes į vieną konteinerį. Tai palengvina jūsų aplikacijos diegimą bet kurioje aplinkoje, kuri palaiko Docker.
Išvada
TypeScript siūlo žymų patobulinimą, palyginti su tradiciniu JavaScript, kuriant tvirtas ir plečiamas serverio pusės aplikacijas su Node.js. Pasitelkę tipų saugumą, patobulintą IDE palaikymą ir pažangias kalbos funkcijas, galite sukurti lengviau prižiūrimas, patikimesnes ir efektyvesnes backend sistemas. Nors įsisavinant TypeScript reikia tam tikro mokymosi, ilgalaikė nauda kodo kokybės ir kūrėjų produktyvumo atžvilgiu daro tai verta investicija. Kadangi gerai struktūrizuotų ir lengvai prižiūrimų aplikacijų paklausa toliau auga, TypeScript yra pasirengęs tapti vis svarbesniu įrankiu serverio pusės kūrėjams visame pasaulyje.