Angular.js

Quickstart: Angular2 with TypeScript and Gulp

Angular2 is around the corner. The new version of the framework is much simpler to learn thanks to easier and more concise concepts like component-based architecture, new dependency injection or built-in modularity. In this step-by-step tutorial you will learn how how to get started with Angular2 with TypeScript and Gulp. Source code available on Github.

Introduction

Angular 1.x is probably still the most popular Front-end framework these days and there is no doubt Angular 1.x is a great framework. However it is incredibly difficult to master. The complex API and many concepts introduced since its launch make understanding the framework and thus using it effectively really hard.

Angular2, on the other hand, is a new opening. The new version of the framework is much simpler to learn thanks to easier and more concise concepts like component-based architecture, new dependency injection or built-in modularity.

If you want to practice and start learning Angular2 there is no better place than angular.io. But if you are looking for the ways of utilizing Angular2 with Gulp – this tutorial is for you.

Note: The source code for this article can be found on Github: https://github.com/kolorobot/angular2-typescript-gulp. I assume the repository gets updated quite often.

Project layout

The initial project is based on the Angular2 Quickstart: https://angular.io/docs/ts/latest/quickstart.html with some changes. The most important change is to separate source files from build files: src directory contains all the source files and build contains all compiled and processed files. The server uses build directory as a base directory to serve content.

angular2-typescript-gulp
|   .gitignore
|   bs-config.json  -> BrowserSync configuration
|   gulpfile.ts     -> Gulp in TypeScript
|   package.json    -> npm configuration
|   tsconfig.json   -> TypeScript configuration
|   typings.json    -> TypeScript typings definitions
|
\---src
    |   index.html  -> Starting point for the application
    |
    \---app         -> Application modules
            app.component.ts -> Main application component
            app.html         -> Main application template
            main.ts          -> Application bootstrap

The script for creating directory structure:

mkdir angular2-typescript-gulp\src\app
cd angular2-typescript-gulp
touch .gitignore bs-config.json gulpfile.ts package.json tsconfig.json typings.json
cd src
touch index.html
cd app
touch app.component.ts app.html main.ts

NPM global dependencies

Assuming node and npm is already installed, you may install global dependencies by invoking the following command:

npm i -g <dependency>

Required global dependencies in order to run the project:

  • gulp and gulp-cli (3.9.1)
  • typings (0.6.8)
  • typescript (1.8.2)
  • ts-node (0.5.5)

TypeScript confguration – tsconfig.ts

Compiled files will be saved intto build/app. Please note that gulpfile.ts is excluded from the compilation.

{
  "compilerOptions": {
    "outDir": "build/app",
    "target": "es5",
    "module": "system",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  },
  "exclude": [
    "gulpfile.ts",
    "node_modules",
    "typings/main",
    "typings/main.d.ts"
  ]
}

Note: If you import your project to IDE (e.g. IntelliJ) let the IDE use this file too.

Typings – typings.json

To get started we need only one definition run the following command:

typings install es6-shim –ambient –save

which will append the following content to typings.json

{
  "ambientDependencies": {
    "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c"
  }
}

Typings will be download to typings directory and they will be downloaded on npm install.

npm configuration – package.json

{
  "name": "angular2-typescript-gulp",
  "version": "1.0.0",
  "description": "Angular2 with TypeScript and Gulp QuickStart",
  "scripts": {
    "clean": "gulp clean",
    "compile": "gulp compile",
    "build": "gulp build",
    "server": "lite-server",
    "postinstall": "typings install"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/kolorobot/angular2-typescript-gulp.git"
  },
  "author": "Rafał Borowiec",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/kolorobot/angular2-typescript-gulp/issues"
  },
  "dependencies": {
    "angular2": "2.0.0-beta.7",
    "systemjs": "0.19.22",
    "es6-promise": "^3.0.2",
    "es6-shim": "^0.33.3",
    "reflect-metadata": "0.1.2",
    "rxjs": "5.0.0-beta.2",
    "zone.js": "0.5.15"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "del": "^2.2.0",
    "gulp": "^3.9.1",
    "gulp-typescript": "^2.12.0",
    "gulp-sourcemaps": "^1.6.0",
    "lite-server": "^2.1.0",
    "typescript": "^1.8.2",
    "typings": "^0.6.8"
  }
}

A word about scripts:

  • clean – removes build directory
  • compile – TypeScript compilation (with sourcemaps)
  • build – build the project
  • server – runs lite server which uses configuration from bs-config.json

BrowserSync configuration (lite-server)

By default the content is served from the current directory so this needs to be changed. And since Lite Server uses BrowserSync it enough to provide bs-config.json that configures the server to serve content from build directory.

{
  "port": 8000,
  "files": [
    "build/**/*.{html,htm,css,js}"
  ],
  "server": {
    "baseDir": "build"
  }
}

Building the project with Gulp

To get started we need a task(s) that compiles TypeScript files, copies assets and dependencies to a build directory. Several tasks are needed in order to achieve it.

var gulp = require("gulp");
var del = require("del");
var tsc = require("gulp-typescript");
var sourcemaps  = require('gulp-sourcemaps');
var tsProject = tsc.createProject("tsconfig.json");

/**
 * Remove build directory.
 */
gulp.task('clean', (cb) => {
    return del(["build"], cb);
});

/**
 * Compile TypeScript sources and create sourcemaps in build directory.
 */
gulp.task("compile", () => {
    var tsResult = gulp.src("src/**/*.ts")
        .pipe(sourcemaps.init())
        .pipe(tsc(tsProject));
    return tsResult.js
        .pipe(sourcemaps.write("."))
        .pipe(gulp.dest("build"));
});

/**
 * Copy all resources that are not TypeScript files into build directory.
 */
gulp.task("resources", () => {
    return gulp.src(["src/**/*", "!**/*.ts"])
        .pipe(gulp.dest("build"))
});

/**
 * Copy all required libraries into build directory.
 */
gulp.task("libs", () => {
    return gulp.src([
            'es6-shim/es6-shim.min.js',
            'systemjs/dist/system-polyfills.js',
            'angular2/bundles/angular2-polyfills.js',
            'systemjs/dist/system.src.js',
            'rxjs/bundles/Rx.js',
            'angular2/bundles/angular2.dev.js',
            'angular2/bundles/router.dev.js'
        ], {cwd: "node_modules/**"}) /* Glob required here. */
        .pipe(gulp.dest("build/lib"));
});

/**
 * Build the project.
 */
gulp.task("build", ['compile', 'resources', 'libs'], () => {
    console.log("Building the project ...")
});

Installing dependencies and checking the build

It is a high time to install all dependencies. Run:

npm install

node_modules and typings directories should be created during the install.

Build the project:

npm run clean & npm run build

build directory should be created during the build

build                                
|   index.html                       
|                                    
+---app                              
|       app.component.js       
|       app.component.js.map      
|       app.html                     
|       main.js                      
|       main.js.map
|                                    
\---lib                              
    +---angular2                     
    |   \---bundles                  
    |           angular2-polyfills.js
    |           angular2.dev.js      
    |           router.dev.js        
    |                                
    +---es6-shim                     
    |       es6-shim.min.js          
    |                                
    +---rxjs                         
    |   \---bundles                  
    |           Rx.js                
    |                                
    \---systemjs                     
        \---dist                     
                system-polyfills.js  
                system.src.js

Run the server:

npm run server

The empty page should be displayed in the browser.

Creating the application

All the basic infrastucture is in place. It is a high time to create the application.

src/app/app.component.ts

import {Component} from "angular2/core";
import {OnInit} from "angular2/core";

@Component({
    selector: "app",
    templateUrl: "./app/app.html"
})
export class AppComponent implements OnInit {

    ngOnInit() {
        console.log("Application component initialized ...");
    }
}

src/app/app.html

<p>Angular 2 is running ... </p>

src/app/main.ts

import {bootstrap} from "angular2/platform/browser";
import {AppComponent} from "./app.component";

bootstrap(AppComponent);

src/index.html

The libraries are reference from lib directory that is created during the build task.

<html>
<head>
    <title>Angular 2 TypeScript Gulp QuickStart</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- 1. Load libraries -->
    <!-- IE required polyfills, in this exact order -->
    <script src="lib/es6-shim/es6-shim.min.js"></script>
    <script src="lib/systemjs/dist/system-polyfills.js"></script>

    <script src="lib/angular2/bundles/angular2-polyfills.js"></script>
    <script src="lib/systemjs/dist/system.src.js"></script>
    <script src="lib/rxjs/bundles/Rx.js"></script>
    <script src="lib/angular2/bundles/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
        System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('app/main')
                .then(null, console.error.bind(console));
    </script>

</head>

<!-- 3. Display the application -->
<body>
<app>Loading...</app>
</body>

</html>

Building and running

npm run clean & npm run build
npm run server

Notes on IntelliJ

IntelliJ handles the proposed setup with no problem. If TypeScript compiler is used in IntelliJ it should use the project’s tsconfig.json. In such case, changes to ts files will be reflected in build directory immediately.

Source code

https://github.com/kolorobot/angular2-typescript-gulp

What’s next?

Much more is needed to make real use of this project. Therefore more features will be added soon. If you have any suggestion, comment or add Github issues.

angular2-seed

If you need more mature starter, have a look at angular2-seed project https://github.com/mgechev/angular2-seed. angular2-seed uses gulp in much more advanced way and it is already supporting production and development build, unit and integration tests and many more.

Reference: Quickstart: Angular2 with TypeScript and Gulp from our WCG partner Rafal Borowiec at the Codeleak.pl blog.

Rafal Borowiec

Rafal is an IT specialist with about 8 years of commercial experience, specializing in software testing and quality assurance, software development, project management and team leadership. He is currently holding a position of a Team Leader at Goyello where he is mainly responsible for building and managing teams of professional developers and testers. He is also responsible for maintaining relations with customers and acquiring new ones, mainly through consultancy. He believes in Agile project management and he is a big fan of technology, especially Java related (but not limited too). He likes sharing knowledge about software development and practices, through his blog (blog.codeleak.pl) and Twitter (@kolorobot) but also on internal and external events like conferences or workshops.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button