Sådan konfigureres et Express.js API ved hjælp af Webpack og TypeScript.

Foto fra https://unsplash.com/photos/95YRwf6CNw8

Forudsætninger.

  • Grundlæggende typeskrift og webpack viden
  • Garn eller npm. I denne tutorial vil jeg bruge garn.
  • node.js
  • Kodeditor efter eget valg.

Her er linket til repoen med det færdige opsætning i tilfælde af, at du sidder fast.

Opsætning af appen.

  1. Åbn din terminal og opret en ny mappe til din applikation. Jeg vil bruge navnet express-app til denne tutorial, men du kan bruge ethvert navn.
mkdir express-app
cd ekspres-app

2. Opret en package.json-fil i mappen ovenfor ved at køre garn init -y. Jeg brugte -y-flaget til at acceptere standardgarnmulighederne, men det kan du også.

3. Opret en src / mappe, og opret deri en index.ts-fil. Dette er indgangsfilen til applikationen.

4. Opret en webpack.config.js-fil i express-app-mappen, og tilføj følgende config.

const path = kræve ('sti');
const {
  NODE_ENV = 'produktion',
} = proces.env;
module.exports = {
  post: './src/index.ts',
  tilstand: NODE_ENV,
  mål: 'node',
  output: {
    sti: path.resolve (__ dirname, 'build'),
    filnavn: 'index.js'
  },
  beslutte: {
    udvidelser: ['.ts', '.js'],
  }
}

5. Tilføj et build-script i filen package.js.

...
"scripts": {
  "build": "webpack"
}

Kør theyarn build-kommando i terminalen som en røgprøve for opsætningen.

6. Installer ekspress, og det er typedefinitionsfiler (@typer / ekspress) ved hjælp af garn tilføj ekspress @ typer / ekspresand opret en simpel ekspressapp i src / index.ts som vist nedenfor. Type-definition-filer gør det muligt for os at nyde fordelene ved typekontrol.

import * som udtryk fra 'udtrykke';
import {Request, Response} fra 'express';
const app = express ();
const {
  PORT = 3000,
} = proces.env;
app.get ('/', (req: Forespørgsel, res: Response) => {
  res.send ({
    besked: 'hej verden',
  });
});
app.listen (PORT, () => {
  console.log ('server startede på http: // localhost:' + PORT);
});

Filen ovenfor kan ikke bygges af webpack ud af boksen. Vi er nødt til at tilføje ts-loader for at gøre det muligt for webpack at bygge den med succes.

7. Kør garn tilføj ts-loader-typeskrift - ev. Pakken ts-loader afhænger af den typeskriftpakke. Disse er begge udviklingsafhængigheder.

8. Tilføj en typescript-konfigurationsfil - tsconfig.json i projektets rodmappe, og tilføj følgende.

{
  "compilerOptions": {
    "sourceMap": sandt
  }
}

9. Føj følgende webpack-konfiguration til webpack.config.js-filen.

...
module.exports = {
  ...
  modul: {
    regler: [
      {
        test: /\.ts$/,
        brug: [
          'Ts-loader',
        ]
      }
    ]
  }
}

10. Kør garnbygning for at teste bygningen. Dette giver en fejl, der siger "Kan ikke finde navnet 'proces'". Vi kan løse dette ved at tilføje typedefinitionsfiler til node.js ved hjælp af garn add @ types / node --dev.

11. Optimering. Hvis du åbner build / index.js, er den første ting, du bemærker, at filen er for stor. Det skyldes, at nogle afhængigheder - pakker i mappen node_moduler tilføjes i bundtet. Dette gør byggeprocessen langsom.

For at løse dette skal vi bruge webpakkens konfigurationsmulighed for eksterne. Dette giver os mulighed for at ekskludere nogle pakker fra bundtet.

Kør garn tilføj webpack-node-externals --dev og tilføj følgende config til webpack.config.js

const nodeExternals = kræve ('webpack-node-externals');
module.exports = {
  ...
  eksterne: [nodeExternals ()]
}

Kør garnbygning. Filen build / index.js skal være meget mindre i størrelse, og byggetiden bør reduceres betydeligt.

12. Kør applikationen vha. Node build / node.js. Og naviger til http: // localhost: 3000 i din webbrowser.

13. Forbedring. Hvis du udvikler en app med denne opsætning, kan du muligvis have en opsætning, hvor appen automatisk indlæses igen på gem. Lad os udnytte webpakkens valgmulighed for konfiguration som vist nedenfor.

module.exports = {
  ...
  se: NODE_ENV === 'udvikling'
}

Tilføj et start: dev-script i package.json.

...
"scripts": {
  ...
  "start: dev": "NODE_ENV = udviklingswebpakke",
}

Kør garnstart: dev. Med NODE_ENV sat til at udvikle sig, ser webpack vores appfiler og genopbygges ved at gemme.

Derefter skal vi køre appen, når build / index.js-filen ændres. Lad os udnytte nodemon og webpack-shell-plugin. Webpack-shell-plugin tillader os at køre starte appen ved hjælp af nodemon, når webpack er færdig med at bygge.

Installer pakkerne ovenfor ved hjælp af garn tilføj - dev nodemon webpack-shell-plugin.

Tilføj et run: dev-script i package.json.

...
"scripts": {
  ...
  "run: dev": "NODE_ENV = udvikling nodemon build / index.js"
}

Tilføj følgende i webpack.config.js.

...
const WebpackShellPlugin = kræve ('webpack-shell-plugin');
module.exports = {
  ...
  plugins: [
    ny WebpackShellPlugin ({
      onBuildEnd: ['garn run: dev']
    })
  ]
}

Jeg brugte indstillingen onBuildEnd i webpack-shell-plugin, fordi det kun kører de (n) angivne kommando (er) efter den første build. Ved efterfølgende builds genstarter appen automatisk.

Kør garnstart: dev for at køre appen i udviklingsfunktion.

Opsætning af enhedstest

Til test skal vi bruge jest som vores testløber og supertest til test af ekspressappen. Fantastisk support til typeskrift med en lille konfiguration.

  1. Installer jest, @ types / jest, ts-jest og supertest som udviklingsafhængigheder ved hjælp af garn tilføj jest supertest @ types / jest ts-jest --dev.
  2. Tilføj nogle konfiguration for jest. Opret en jest.config.js-fil i det samme bibliotek som package.json med følgende indhold.
module.exports = {
  testMiljø: 'node',
  transform: {
    "^. + \\. ts $": "ts-jest"
  },
};

Konfigurationen ovenfor fortæller jest at transformere typeskriptfiler til js, før testene køres.

3. Opret en testmappe på samme niveau som src / mappen. Dette vil indeholde tests, og dets indhold spejler indholdet af src /.

4. Opret en fil med navnet index.test.ts i testene / mappen med følgende indhold. Alle testfilnavne slutter i .test.ts.

import app fra '../src/index';
import * som supertest fra 'supertest';
beskriv ('app', () => {
  lad anmodning;
  beforeEach (() => {
    anmodning = supertest (app);
  });
  it ('skal returnere et vellykket svar for GET /', done => {
    request.get ( '/')
      . udsigt (200, færdig);
  });
});

5. Lad os ændre src / index.ts for at eksportere appvariablen som en standardeksport og start kun serveren, hvis filen udføres i modsætning til at blive importeret.

...
if (kræve.main === modul) {// sandt, hvis filen udføres
  app.listen (PORT, () => {
    console.log ('server startede på http: // localhost:' + PORT);
  });
}
eksport standard app;

6. Tilføj et "test" script i package.json.

...
"scripts": {
  ...
  "test": "jest"
}

7. Kør garntest for at køre enhedstesten ovenfor. Dette er jest, du kan også videregive nogle flag såsom garnetest - ur for at se filerne, garntest - dækning for at lade jest samle testdækning.

Endelige tanker.

Kørselstart: dev giver en advarsel om afskrivning. Dette skyldes, at webpack-shell-plugin bruger webpacks gamle plugin-API. Du kan følge op om dette spørgsmål.