【Trainer's Recipe】Angular2を始めるための第一歩

このEntryは、<a href="http://gsacademy.tokyo/" target="_blank" style="text-decoration: none;">G's ACADEMY TOKYO</a>のトレーナー/チューターによる投稿記事です。
授業の中で出たちょっとした質問や疑問、トレーナーが関心のある新技術等を脈絡なく綴っていきます。

<img width="498" alt="angular2.png" src="https://qiita-image-store.s3.amazonaws.com/0/104065/2a817fc4-0df2-4755-04b8-2a2f853d5b4a.png">


こんにちは！
ジーズアカデミーチューターの岸です。

JavaScriptフレームワークのひとつであるAngularJSの最新バージョン「Angular2」の正式リリースが間近に迫っていますね！

今回は、そのAngular2をとにかく簡単にさくっと試せる簡単な手順をご紹介します！


#Angular2でHello World的なことをする
以下の公式のチュートリアル(英語)に基いています。
https://angular.io/docs/ts/latest/quickstart.html
Angular2は、JavaScriptの他にTypeScript、Dartでも書けますが、推奨されているTypeScriptで進めていきます。

※手順をrc.5の内容に書き換えました。ご指摘いただきまして誠にありがとうございました。


##環境構築
アプリケーションを動作させるためのフォルダ(以下、アプリケーションフォルダ)を作成します。

```
$ mkdir angular2-quickstart
$ cd angular2-quickstart
```

ローカルにnpmパッケージをインストールします。
Node.jsがインストールされていない方は、[こちら](https://nodejs.org/en/download/)からインストールしてください。

npmは以下のコマンドでインストールできます。

```
$ npm install npm -g
```

以下の4ファイルをアプリケーションフォルダ直下に作成します。

1.package.json - アプリケーションで使用するパッケージやスクリプトを定義するファイル

```json:package.json
{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "2.0.0-rc.5",
    "@angular/compiler": "2.0.0-rc.5",
    "@angular/core": "2.0.0-rc.5",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "@angular/platform-browser": "2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.5",
    "systemjs": "0.19.27",
    "core-js": "^2.4.0",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "zone.js": "^0.6.12",
    "angular2-in-memory-web-api": "0.0.15",
    "bootstrap": "^3.3.6"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.2.0",
    "typescript": "^1.8.10",
    "typings":"^1.0.4"
  }
}
```

2.tsconfig.json - TypeScriptコンパイラの設定ファイル

```json:tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}
```

3.typings.json - TypeScriptの定義ファイル

```json:typings.json
{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160807145350"
  }
}
```

4.systemjs.config.js - SystemJSの設定ファイル

```js:systemjs.config.js
/**
 * System configuration for Angular 2 samples
 * Adjust as necessary for your application needs.
 */
(function(global) {
  // map tells the System loader where to look for things
  var map = {
    'app':                        'app', // 'dist',
    '@angular':                   'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs':                       'node_modules/rxjs'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };
  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/'+pkgName] = { main: 'bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  }
  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);
  var config = {
    map: map,
    packages: packages
  };
  System.config(config);
})(this);
```

package.jsonに記述された各npmパッケージをインストールします。

```
$ npm install
```

typingsフォルダが生成されないことがありますので、その場合は手動でインストールします。

```
$ npm run typings install
```

##ファイルを作成
アプリケーションフォルダ直下にappフォルダを作成します。

```
$ mkdir app
```

appフォルダの直下に以下の3ファイルを作成します。

1.app.component.ts - アプリケーションのコンポーネントを記述したファイル

```ts:app.component.ts
import { Component } from '@angular/core';
@Component({
  selector: 'my-app',
  template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }
```

2.app.module.ts - アプリケーションを構成するためのモジュールを記述したファイル

```ts: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 { }
```

3.main.ts - アプリケーションを起動するために必要なものを呼び出すファイル

```ts:main.ts
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
```

さらに、アプリケーションフォルダ直下に、HTMLファイルおよびCSSファイルを作成します。

```html:index.html
<html>
  <head>
    <title>Angular 2 QuickStart</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">
    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <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/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>
    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err); });
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>
```

```css:styles.css
/* Master Styles */
h1 {
  color: #369;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 250%;
}
h2, h3 {
  color: #444;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: lighter;
}
body {
  margin: 2em;
}
```


最終的なファイル構成は以下のとおりになります。

```
angular2-quickstart
|
├─app
|  ├─app.component.ts
|  ├─app.module.ts
|  └─main.ts
├─node_modules ...
├─typings ...
├─index.html
├─package.json
├─styles.css
├─systemjs.config.js
├─tsconfig.json
└─typings.json
```

#実行
以下のコマンドで実行します。

```
$ npm start
```

うまくいくと以下の画面が表示されます。

![angular2_demo1.png](https://qiita-image-store.s3.amazonaws.com/0/104065/e16be3b7-e361-d2c6-835a-75e6134ee2c5.png)

#Angular Componentの中身を変更してみる
app.component.tsの中にある@Componentの中身をちょっと書き換えたいと思います。
app.component.tsを以下のように書き換えてみます。

```ts:app.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: 'template.html',
    styleUrls: ['template.css']
})

class AppComponent { }
```

アプリケーションフォルダの直下にテンプレートのhtmlファイル、それに適用するCSSファイルを作成します。

```html:template.html
<h1>テンプレートです。</h1>
```

```css:template.css
h1 {
	color: red;
}
```


これで実行してみると・・・

![angular2_demo2.png](https://qiita-image-store.s3.amazonaws.com/0/104065/fae9510f-a31a-fa7a-f80d-6baf5568d272.png)


別ファイルとして分離したhtmlとcssがComponentのテンプレート、スタイルとして適用されていることを確認できました。


次に、AngularJSの特徴のひとつであるデータバインディングを試してみます。

app.component.tsとtemplate.htmlを以下のように書き換えてみます。

```ts:app.component.ts
import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    templateUrl: 'template.html',
    styleUrls: ['template.css']

})

export class AppComponent {
    message = 'コンポーネントからのメッセージです。'
}
```

```html:template.html
<h1>{{message}}</h1>
```
これで実行してみると・・・

![angular2_demo3.png](https://qiita-image-store.s3.amazonaws.com/0/104065/5af6be14-174c-a6a1-dc77-ca2ca0d51e5f.png)

データバインディングがされていることが確認できました。



以上、簡単ではありましたが、Angular2をさくっと試せる手順をご紹介しました。

Angular2に興味があるけどまだ触ってすらいない・・・という方は、ぜひチャレンジしてみてはいかがでしょうか？

以上、<a href="http://gsacademy.tokyo/" target="_blank" style="text-decoration: none;">G's ACADEMY TOKYO</a>チューターの岸によるTrainer's Recipeでした。