Hello Angular Typescript

29 December 2016

Angular is one of many open source frameworks for developing web applications. I may have not seen all of them but this is the closest I think to Java and its metadata approach to programming. Another Javascript framework I wanted to use is nodejs but this is more than just a framework or library but a runtime environment if you like.

Angular Toolset

You will get this with any language you wanted to use, you need to set up its environment. node and npm is a must when writing Angular.

$ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
Fetched 313 kB in 0s (484 kB/s)    

## Run `apt-get install nodejs` (as root) to install Node.js v7.x and npm

$ sudo apt-get install nodejs
Fetched 10.9 MB in 2s (4,238 kB/s)

$ node -v
v7.3.0

$ npm -v
3.10.10

Creating hello angular project

$ mkdir hello-typescript

$ cd hello-typescript

$ npm init -y

npm init will create the starter package.json where I'm going to add the project dependencies. This is the pom.xml or the build.gradle or the build.sbt of the JVM world if you know what I mean.

Folder Structure

This is my hello-typescript folder structure. This will grow once you run npm install.

├── app
│   ├── app.component.ts
│   ├── app.module.ts
│   └── main.ts
├── index.html
├── package.json
├── systemjs.config.js
└── tsconfig.json

package.json

The private: true will prevent the package from being accidentally published to the npm registry.

{
  "name":         "hello-typescript",
  "version":      "1.0.0",
  "description":  "Hello angular typescript project",
  "private":      true,
  "main":         "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "live-server"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0",
    "@angular/compiler": "2.0.0",
    "@angular/core": "2.0.0",
    "@angular/forms": "2.0.0",
    "@angular/http": "2.0.0",
    "@angular/platform-browser": "2.0.0",
    "@angular/platform-browser-dynamic": "2.0.0",
    "@angular/router": "3.0.0",
    "core-js": "^2.4.0",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.37",
    "zone.js": "0.6.21"
  },
  "devDependencies": {
    "live-server": "0.8.2",
    "typescript": "^2.0.0"
  }
}

tsconfig.js

{
  "compilerOptions": {
    "target": "ES5",
    "module": "commonjs",
    "experimentalDecorators": true,
    "noImplicitAny": true
  }
}

This is the Typescript configuration where you specify your transpiler output. ES5 is chosen since no browser can natively load ECMAScript 6 modules.

systemjs.config.js

System.config({
    transpiler: 'typescript',
    typescriptOptions: {emitDecoratorMetadata: true},
    map: {
      '@angular': 'node_modules/@angular',
      'rxjs'    : 'node_modules/rxjs'
    },
    paths: {
      'node_modules/@angular/*': 'node_modules/@angular/*/bundles'
    },
    meta: {
      '@angular/*': {'format': 'cjs'}
    },
    packages: {
      'app'                              : {main: 'main', defaultExtension: 'ts'},
      'rxjs'                             : {main: 'Rx'},
      '@angular/core'                    : {main: 'core.umd.min.js'},
      '@angular/common'                  : {main: 'common.umd.min.js'},
      '@angular/compiler'                : {main: 'compiler.umd.min.js'},
      '@angular/platform-browser'        : {main: 'platform-browser.umd.min.js'},
      '@angular/platform-browser-dynamic': {main: 'platform-browser-dynamic.umd.min.js'}
    }
});

systemjs is a module loader that can import at run time in any of the popular formats used today. This allows you to use import statements to load even third-party code. It solves the issue with the loading order of scripts and makes sure the application loads only those modules that it actually uses.

The app folder

It contains the following files:

app.component.ts

import { Component } from '@angular/core';

@Component({
    selector: 'app',
    template: `<h1>Hello {{ name }}!</h1>`
})

export class AppComponent {
    name: string;

    constructor() {
        this.name = 'Angular 2';
    }
}

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }  from './app.component';

@NgModule({
    imports:      [ BrowserModule ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})

export class AppModule { }

main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule }  from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

index.html

<!DOCTYPE html>
<html>
<head>
  <title>Hello typescript project</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script src="node_modules/typescript/lib/typescript.js"></script>
  <script src="node_modules/core-js/client/shim.min.js"></script>
  <script src="node_modules/zone.js/dist/zone.js"></script>
  <script src="node_modules/systemjs/dist/system.src.js"></script>
  <script src="systemjs.config.js"></script>
  <script>
    System.import('app').catch(function(err){ console.error(err); });
  </script>
</head>

<body>
  <app>Loading...</app>
</body>
</html>

Running hello-typescript

$ npm install

$ npm start

> hello-typescript@1.0.0 start /home/drmanalo/angular/hello-typescript
> live-server

Serving "/home/drmanalo/angular/hello-typescript" at http://127.0.0.1:8080