Getting started with express and typescript
I recently started an ExpressJS project, and I wanted to use Typescript, as I thought my project would benefit from the typed language and stricter structure.
I had a bit of trouble setting up when following other tutorials, so of course the right thing to do was to write my own.
This is a continuation of my previous tutorial, so I’ll assume you at least have node installd – if not follow my guide to getting started with nodejs first.
It also assumes you have some basic knowledge of express and typescript already, so it’s not about these components but rather about putting them together.
You want to start a new project, and install express
as usual:
npm init npm install --save express hbs npm install --save-dev @types/express @types/node
The latter command will install typescript type definitions for express and node
Now you can write your typescript classes and use express. This is a basic hello world page, src/app.ts
:
import * as express from "express"; import * as path from "path"; class App { public express; constructor() { this.express = express(); this.mountHomeRoute(); this.prepareStatic(); this.setViewEngine(); } // This serves everything in `static` as static files private prepareStatic(): void { this.express.use(express.static(path.join(__dirname, "/../static/"))); } // Sets up handlebars as a view engine private setViewEngine(): void { this.express.set("view engine", "hbs"); this.express.set("views", path.join(__dirname, "/../src/views")); } // Prepare the / route to show a hello world page private mountHomeRoute(): void { const router = express.Router(); router.get("/", (req, res) => { res.json({ message: "Hello World!" }); }); this.express.use(‘/’, router) } } export default new App().express;
You don’t need to do everything that I’m doing here, you could only keep the call to mountHomeRoute()
and you’d still get your hello world app.
You can also see that you can still use express features like the router and views the same way as you would with plain javascript!
Once you’ve written your class to set up the express app, all you need is server.ts
to start the server.
import app from "./app"; const port = process.env.PORT || 3000; app.listen(port, (err) => { if (err) { return console.log(err); } return console.log(`server is listening on ${port}`); });
Now that you have your typescript written, you can compile it into plain javscript.
First of all, you need typescript if you haven’t got it yet:
npm install -g typescript
This should give you the tsc
command. Now, to compile all of your files under src
, you can do the following:
tsc --outDir dist src/**/*
This tells the typescript compiler to compile all the files inside src/
to the dis
directory. If you look at dist
, it should have your generated files:
$ ls dist app.js server.js
Now to start your app you need to run the server.js
file, which is the compiled javascript (not server.ts
):
node dist/server.js
And if you navigate to http://localhost:3000/
, you should see your app!
If you run your app using nodemon
, it will automatically be restarted every time you re-compile, so all you need to do is re-run tsc
.
Configuring the compiler
If you don’t want to have to run tsc --outDir dist src/**/*
you can configure the compiler so you don’t have to give the options every time.
All you have to do is create tsconfig.json
with the options you want:
{ "compilerOptions": { "target": "es6", "module": "commonjs", "outDir": "dist", "sourceMap": true, "baseUrl": ".", "paths": { "*": [ "node_modules/*", "src/types/*" ] } }, "include": [ "src/**/*" ], "exclude": [ "node_modules" ] }
The outDir
option should be familiar from default; by setting this to dist
, tsc
will automatically put all your generated files in the dist
directory.
include
tells the compiler where to look for typescript files, in this case src/**/*
.
"targer": "es6"
is also important if you want es6 support.
If you want to see the full documentation for tsconfig.json, you can find it in the typescript hadnbook.
Once you have tsconfig.json
ready, you can just use tsc
to compile your code without having to manually specify options.
Next steps
From here on you should be ready to go! For more information, check out the following:
You have one major mistake in your code; you don’t use that route anywhere, so it won’t work.
Here is the fixed code:
private mountHomeRoute (): void {
const router = express.Router()
router.get(‘/’, (req, res) => {
res.json({
message: ‘Hello World!’
})
})
this.express.use(‘/’, router)
}
Thanks for pointing it out, I’ll update