Express Angular2 Application Using Typescript [ Server setup ]

Introduction

Documenting the steps which I had to go through inorder to get an Angular2+ExpressJS+Typescript application up and running using Visual Studio Code. The final project will be made available as a seed project in github.

https://github.com/rmchndrng/XprssNg2TSSeed

Pre-requisites

Visual Studio Code NodeJS NPM Typescript

Project Initialization in VS Code

Create a folder with the name of your project (eg:XprssNg2TSSeed)

Open the project in VSCode.(ie. Open the folder in VSCode)

It is always useful to open the terminal/cmd along with it, since we will be running many command line tools to get the tools and packages required for the project.

Initialize the project for NPM

npm init

This will initialize the package.json which will be used by npm. You can provide the values as they are prompted or continue with the defaults.(By pressing Enther key)

Get a simple ExpressJS server up and running

Install ExpressJS

Using npm install express node module.

npm install express --save

“npm install” command will download the package and its dependencies from the repository and place it inside “node_modules” folder. “–save” parameter will add the installed package as a dependency into the package.json config file.

Install Typescript and Typings

Since our goal is to develop the application using typescript, we need to install typescript and typings.

npm install -g typescript --save-dev npm install -g typings --save-dev

This will install the node package “typings”. “-g” parameter will add the package to the global node package registry on the machine. “–save-dev” parameter will add the package into devDependencies. (Development environment dependency) in package.json. (Meaning, the package will be installed locally when we run “npm install” on the project)

“typescript” transpiles/compiles the Typescript we write into javascript based on compilerOptions we specify.

“typings” help us to manage type definitions for all the modules we are going to use. (“tsd” has been deprecated”)

Typescript Initialization

Create a folder by the name “server”. This will hold all the NodeJS server code.

cd server typings init

This will initialize the folder for typings with “typings.json” config file.

Add a new file by the name “tsconfig.json”. This file will hold the configuration used for compiling typescript.

server/tsconfig.json { "compilerOptions": { "target": "ES5", "module": "commonjs", "noEmitOnError": true, "noImplicitAny": true, "experimentalDecorators": true, "sourceMap": true } }

“tsconfig.json” is a first class citizen in VS Code, allowing it to configure tasks to build the project easily. VSCode Task configuration

Since our project is going to hold both server side code as well as client side logic, the settings will vary for each compilation. So we have to make use of gulp tasks to achieve the desired compilation.

Install ExpressJS type definitions

typings install express --ambient --save

This will install type definitions for express and add it as a dependency (“–save” parameter) in the typings.json file. “–ambient” parameter will install the type definition as an Ambient type definition.

A type definition can be of 2 types 1. Ambient - Type definitions contain only declarations and exports of all the methods and properties available for the package. This is mainly because of the fact that the package was originally written in javascript. 2. Non-Ambient - Type definitions comes as part of the package which will contain the actual types. This is specified using the “typings” property in package.json. For more details refer here

HelloWorld Server

A simple HelloWorld express application will look like this. (Click here)

var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send('Hello World!'); }); app.listen(3000, function () { console.log('Example app listening on port 3000!'); });

Inorder to achieve the same using typescript, we will add the following files.

server/serverApp.ts

import * as express from 'express' export class ServerApp { private _App: express.Express; constructor() { this._App = express(); } public setRoutes() { this._App.get('/', this._RenderHelloWorld); } public startServer() { this._App.listen(5000, function () { console.log('Example app listening on port 5000!'); }); } private _RenderHelloWorld(req: express.Request, res: express.Response) { res.send('Hello World!'); } }

server/index.ts

import {ServerApp} from './serverApp' var serverApp = new ServerApp(); serverApp.setRoutes(); serverApp.startServer();

ERROR - Typescript compilation errors shown

At this stage, there will be typescript compilation errors in our serverApp.ts file.

"Property 'get' does not exist on type 'Express" "Property 'listen' does not exist on type 'Express" "Property 'send' does not exist on type 'Response"

If you go to the definition of Express or Response in index.d.ts typing, you can see they are interfaces which extends core.Express and core.Response. “core” is being imported from “express-serve-static-core” module, which is shown as missing.

Reason

When we ran the typings install for express, the output would have been the following.

When you install any ambient typing, you might end up seeing “typings INFO reference Stripped reference “XXXX/xxx/d.ts” during installation from “YYYY”

Fix

We have to manually install the stripped references recursively.More Info

Running the following commands will fix our issue.

typings install express-serve-static-core --ambient --save typings install node --ambient --save typings install serve-static --ambient --save typings install mime --ambient --save

Configure Task Runner for VS Code

To compile/transpile typescript, we will use “gulp” tasks.

A gulp task can be triggered from VS Code directly by configuring the Task Runner.

In VS Code,

Press Ctrl+Shift+B

This will show you the option to “Configure Task Runner”. Click on it and select the Gulp task runner from the list.

This will add a folder “.vscode” into our project containing a file “tasks.json”.

.vscode/tasks.json

{ // See http://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version" : "0.1.0" , "command" : "gulp" , "isShellCommand" : true , "args" : [ "--no-color" ], "showOutput" : "always" }

Try running the task by pressing “Ctrl+Shift+B”.

[OUTPUT] Running gulp --tasks-simple didn't list any tasks. Did you run npm install? Local gulp not found in e:\TrainingLab\Github\XprssNg2TSSeed Try running: npm install gulp

gulp installation

Run the following command in the project root folder.

npm install gulp -g --save-dev

Try running the task by pressing “Ctrl+Shift+B” again.

[OUTPUT] No gulpfile found

Add gulpfile.js

In the project root folder and a gulpfile configured with the tasks required.

The current task at hand is to compile all the typescript files inside the folder “server”

xprssng2tsseed/gulpfile.js

var gulp = require('gulp'); var ts = require('gulp-typescript'); var path = require('path'); var sourcemaps = require('gulp-sourcemaps'); gulp.task('build:server', function () { var tsProject = ts.createProject(path.resolve('./server/tsconfig.json')); var tsResult = gulp.src([ 'server/**/*.ts', '!server/typings/browser/**/*.ts', '!server/typings/browser.d.ts' ]) .pipe(sourcemaps.init()) .pipe(ts(tsProject)) return tsResult.js .pipe(sourcemaps.write()) .pipe(gulp.dest(path.resolve('./server'))) }); gulp.task('build',['build:server']); gulp.task('default', ['build']);

To achieve this task, we will make use of some other packages.

gulp-typescript - A typescript compiler for gulp with incremental compilation support. npm install gulp-typescript --save-dev gulp-sourcemaps - Source map support for Gulp.js npm install gulp-sourcemaps --save-dev

Successful Build

Now try running the task by pressing “Ctrl+Shift+B”.

[OUTPUT] Using gulpfile e:\TrainingLab\Github\XprssNg2TSSeed\gulpfile.js Starting 'build:server'... Finished 'build:server' after 1.2 s Starting 'build'... Finished 'build' after 15 μs Starting 'default'... Finished 'default' after 6.53 μs

As a result, the compiled javascript files with sourcemaps concatenated would been generated besides the typescript files.

Hide compiled javascript files from VS Code file navigation

We generally do not want to see or manupulate the typescript compiler generated javascript. So it will be very helpful during development to hide them. This can be achieved by adding workspace level setting in VS Code.

Open the Command Palette [Ctrl+Shift+P]. Search for “Workspace” and select “Preferences: Open Workspace Settings”.

Add the following in the file and save.

.vscode/settings.json // Place your settings in this file to overwrite default and user settings. { "files.exclude": { "**/.git": true, "**/.DS_Store": true, "**/*.js": { "when": "$(basename).ts"}, "**/*.js.map": true } }

Now all the javascript files with same name having extension “ts” will be hidden from the workspace.

Run the application

Open command window in the “server” folder and run

node index.js

Open your browser and navigate to localhost:5000

Conclusion

The HelloWorld ExpressJS application using Typescript is up and running…

TODOs

In the following journals, I will try to document the steps to achieve the following goals.

Angular2 Application Setup. Workflow to share Typescript code across Server and Client applications. Incremental compilation and Live reloading of the application. Debugging the ExpressJS Server application using VS Code Debugging the Angular2 Client application using VS Code

References