Setting up a TypeScript + Visual Studio Code development environment

An introduction to the development of TypeScript applications with VS Code

In this post we are going to learn how to configure a TypeScript + VS Code development environment. We are going to use the following tools:

Let’s get started!

Note: The entire VS Code project used in this post is available at GitHub.

1. Download and installing VS Code and some extensions #

We are going to download and install VS Code and some extensions that will help us to maximize our productivity.

uhzasc137en4sg_small.png

Let’s start by downloading VS Code for your OS here and Node.js here.

Let’s now install some VS code extensions. Open VS Code when you are ready and use Shift + Command + p to access the command panel. The command panel will display the matching commands as you type.

Go ahead and type “install extensions”:

Screen Shot 2016-02-13 at 15.49.46.png

Select the Install Extension command and type tslint. Once more the command panel will display matching results in real-time.

Click on the cloud icon to download and install the tslint plugging:

Screen Shot 2016-02-13 at 16.25.45.png

You will need to restart VS Code after instilling an extension to be able to see it in action:

Screen Shot 2016-02-13 at 16.30.37.png

Note The tslint extension requires a global installation of tslint:

$ npm install -g tslint

I would recommend you to check out the VS Code extensions gallery to see if you find an interesting extension. In this post we are going to use the following extensions:

After installing the extensions we need to install some third party dependencies.

Create a new folder for your project and create a new package.json file:

$ mkdir ts-vscode-boilerplate
$ cd ts-vscode-boilerplate
$ npm init

We are now ready to install the third party dependencies:

$ npm install  --save-dev browser-sync
$ npm install  --save-dev browserify
$ npm install  --save-dev chai
$ npm install  --save-dev gulp
$ npm install  --save-dev gulp-istanbul
$ npm install  --save-dev gulp-mocha
$ npm install  --save-dev gulp-sourcemaps
$ npm install  --save-dev gulp-tslint
$ npm install  --save-dev gulp-typescript
$ npm install  --save-dev gulp-uglify
$ npm install  --save-dev run-sequence
$ npm install  --save-dev tslint
$ npm install  --save-dev typescript
$ npm install  --save-dev vinyl-buffer
$ npm install  --save-dev vinyl-source-stream

2. Configuring your VS Code preferences #

The VS Code configuration and preferences are text based. This means that there are no wizards of forms available but don’t worry because the configuration files are really intuitive.

Some of the settings can be configured at user level or project (workspace) level. We are going to change some of the workspace preferences. To access the workspace preferences file you need to visit the preferences area:

Screen Shot 2016-02-13 at 15.27.16.png

Click on “Workspace Settings”. Two files should be displayed on screen:

userandworkspace_settings.png

We are going to be working on a TypeScript application and we are going to store all the .ts source files under two directories named source and test. We don’t want the JavaScript files generated by the TypeScript compiler to be displayed on the project exploration panel. We can achieve this using the files.exclude configuration field.

Let’s add the files.exclude configuration field to the workspace settings file to hide add all the JavaScript files under the source and test directories:

{
    "files.exclude": {
        "**/.git": true,
        "**/.DS_Store": true,
        "source/**/*.js": true,
        "test/**/*.js": true
    }
}

After saving the changes, a file named settings.json will be created under a directory named .vscode.

Note: Please refer to the official docs if you wish to find out more about user and workspace settings.

3. Linting, compiling, bundeling and running your TypeScript code with Gulp + Browserify #

Visual Studio code also allow us to integrate the editor with our favorite task runner or compiler.

Let’s create a new file named gulpfile.js inside the project’s root directory and add the following contents to it.

Note: To access the task runner configuration we need to press Shift + Command + b. We don’t need to do this because VS Code will automatically detect and use Gulp ad the the task runner.

The first thing that we need to do is import all the required third party dependencies:

var gulp        = require("gulp"),
    browserify  = require("browserify"),
    source      = require("vinyl-source-stream"),
    buffer      = require("vinyl-buffer"),
    tslint      = require("gulp-tslint"),
    tsc         = require("gulp-typescript"),
    sourcemaps  = require("gulp-sourcemaps"),
    uglify      = require("gulp-uglify"),
    runSequence = require("run-sequence"),
    mocha       = require("gulp-mocha"),
    istanbul    = require("gulp-istanbul"),
    browserSync = require('browser-sync').create();

Now we are ready to create our first Gulp task. This task is used to lint our TypeScript code:

gulp.task("lint", function() {
    return gulp.src([
        "source/**/**.ts",
        "test/**/**.test.ts"
    ])
    .pipe(tslint({ }))
    .pipe(tslint.report("verbose"));
});

Note: tslint expects to find a file named tslint.json in the root folder of the project. The tslint.json is to configure the TypeScript linter options. The full tslint.json file used in this example is available online.

We can then proceed to write a task to compile our application’s source code:

var tsProject = tsc.createProject("tsconfig.json");

gulp.task("build-app", function() {
    return gulp.src([
            "source/**/**.ts",
            "typings/main.d.ts/",
            "source/interfaces/interfaces.d.ts"
        ])
        .pipe(tsc(tsProject))
        .js.pipe(gulp.dest("source/"));
});

The tsconfig.json file contains the TypeScript compiler settings:

{
    "compilerOptions": {
        "target": "es5",
        "sourceMap": true,
        "module": "commonjs",
        "moduleResolution": "node",
        "isolatedModules": false,
        "jsx": "react",
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true,
        "declaration": false,
        "noImplicitAny": false,
        "removeComments": true,
        "noLib": false,
        "preserveConstEnums": true,
        "suppressImplicitAnyIndexErrors": true
    }
}

The compiled JavaScript uses CommonJS modules and therefore can’t be loaded in a web browser. We are going to write a Gulp task and use Browserify to transom many CommonJS into one single file that can be loaded by a web browser.

gulp.task("bundle", function() {

    var libraryName = "myapp";
    var mainTsFilePath = "source/main.js";
    var outputFolder   = "dist/";
    var outputFileName = libraryName + ".min.js";

    var bundler = browserify({
        debug: true,
        standalone : libraryName
    });

    return bundler.add(mainTsFilePath)
        .bundle()
        .pipe(source(outputFileName))
        .pipe(buffer())
        .pipe(sourcemaps.init({ loadMaps: true }))
        .pipe(uglify())
        .pipe(sourcemaps.write('./'))
        .pipe(gulp.dest(outputFolder));
});

We have also used uglify to reduce the size of the resulting bundled file and increase the performance of our application. Sourcemaps allow us to debug the bundle file in chrome and see the original TypeScript code instead of the compressed JavaScript code.

Finally, we can write a task to observe changes in our code, trigger the compilation process and display changes in a web browser:

gulp.task("watch", ["default"], function () {

    browserSync.init({
        server: "."
    });

    gulp.watch([ "source/**/**.ts", "test/**/*.ts"], ["default"]);
    gulp.watch("dist/*.js").on('change', browserSync.reload); 
});

BrowserSync is not just an HTTP server:

BrowserSync features out-of-the-box cross-device synchronized testing!

Note: The gulpfile.js file used in this example is available online.

Now that our gulpfile.js is ready we can use Shift + Command + p to open command panel and type “run task”:

run-task.png

We can then select “run task” to see available gulp tasks

task-list.png

4. Testing TypeScript code with Mocha, Chai and Wallaby.js #

We are going to also write some unit tests with Mocha and Chai. In order to do so, we need a task to compile our application’s unit tests:

var tsTestProject = tsc.createProject("tsconfig.json");

gulp.task("build-test", function() {
    return gulp.src([
            "test/**/*.ts",
            "typings/main.d.ts/",
            "source/interfaces/interfaces.d.ts"
        ])
        .pipe(tsc(tsTestProject))
        .js.pipe(gulp.dest("test/"));
});

A task to generate tests coverage reports:

gulp.task("istanbul:hook", function() {
    return gulp.src(['source/**/*.js'])
        // Covering files
        .pipe(istanbul())
        // Force `require` to return covered files
        .pipe(istanbul.hookRequire());
});

And a task to run our unit tests:

gulp.task("test", ["istanbul:hook"], function() {
    return gulp.src('test/**/*.test.js')
        .pipe(mocha({ui: 'bdd'}))
        .pipe(istanbul.writeReports());
});

We can see the test and coverage results in console:

Untitled.png

We can do better than that by using Wallaby.js:

Wallaby.js is an intelligent and super fast test runner for JavaScript that continuously runs your tests. It reports code coverage and other results directly to your code editor, immediately as you change your code.

If you have installed the VS Code extension you can use Shift + Command + = and select “Start” to launch Wallaby.js:

enable-wallaby.png

We can then enjoy real-time tests results powered by Wallaby.js:

wallaby.gif

5. Debugging Mocha tests #

If you need to debug your tests you will be able to do so by running the following command:

$ mocha --debug-brk

At that point mocha awaits the debugger to be connected. Select debug in VS Code on the left hand side of the screen and click on the dropdown which current selected value is <none>:

Screen Shot 2016-02-20 at 12.15.26.png

Select Node.js, click again on the dropdown and select attach:

Screen Shot 2016-02-20 at 12.15.34.png

You can then add breakpoints to the JavaScript files generated by the TypeScript compiler.

Note: Remember to make the JS files visible in your settings.json if you want to debug them.

The VS Code debugger has everything you would expect: break points, debug console, call stack…

Screen Shot 2016-02-20 at 12.08.48.png

Summary #

In this post we have configured VS Code to work withTypeScript. We now know how to install VS Code extensions, compile and test our TypeScript code using the productivity power tools like Wallaby.js, tslint and Gulp.

The entire VS Code project used in this post is available at GitHub.

Please feel free to let us know your thoughts about this article via @OweR_ReLoaDeD and @WolkSoftwareLtd.

Don’t forget to subscribe if you don’t want to miss it out future articles!

Update #

The source code used in this article has been updated to TypeScript 2.0 on GitHub. Take a look to this commit to see what needs to be changed.

Visit the GitHub repository at https://github.com/remojansen/ts-vscode-boilerplate for an always up to date version!

 
1,072
Kudos
 
1,072
Kudos

Now read this

Introducing InversifyJS

A lightweight inversion of control container for TypeScript & JavaScript apps # A few months ago I started to think about the possibility of creating a requireJS TypeScript fork in order to add dependency inversion (DI) support.... Continue →