Angularの勉強会に申し込んだので、Angular2を勉強してみることにしました。
Angularとは・・・
- Javascriptのフレームワークです。
- Googleが開発し現在はOSSです。
- SPA(Single Page Application)を作るのによく使われます。
- 2.x系はこの記事を書いている現在はまだBetaです。
- 1.x系とは、基本的に後方互換性がないです。*1
自分は業務ではサーバサイドが多く、Javascriptは専らJQuery育ちです。Backbone以降のJavascriptフレームワークにはおしなべて疎いです。 今回は、Anguluar2の5 min quickstartをやってみました。 そして自分なりにその内容を日本語でまとめてみました。理解に怪しい所が多々あるので、優しい方は指摘頂けると嬉しいです。
quickstartは3バージョンありました。
- Typescript
- Dart
- Javascript
自分はJavascriptバージョンをやりました。
以下、Angularという言葉をバージョンを明示しないで使っていたら全てAngular2(beta)のことです。
プロジェクトの作成
まずは、プロジェクトのディレクトリを作って、そこに移動します。
angular2-quickstart
というディレクトリ名はクイックスタートそのままのディレクトリ名です。
mkdir angular2-quickstart cd angular2-quickstart
次に必要なライブラリをnpm
でインストールするためにpackage.json
を作ります。
npmはnode.jsのパッケージ管理ツールです。nodeをインストールするとnpmも一緒にインストールされるので、入ってない場合は
brew installl node
とかでインストールしておいてください。
ちなみに、自分の環境のnpm
とnode
のバージョンは以下のとおりでした。
➜ angular2-quickstart node -v v5.8.0 ➜ angular2-quickstart npm -v 3.7.3
さて、改めてpackage.json
ファイルを作ります。
touch package.json
ファイルを開いて以下のように書きます。
{ "name": "angular2-quickstart", "version": "1.0.0", "scripts": { "start": "npm run lite", "lite": "lite-server" }, "license": "ISC", "dependencies": { "angular2": "2.0.0-beta.12", "es6-shim": "^0.35.0", "reflect-metadata": "0.1.2", "rxjs": "5.0.0-beta.2", "zone.js": "0.6.6" }, "devDependencies": { "concurrently": "^2.0.0", "lite-server": "^2.1.0" } }
依存ライブラリをインストールします。
npm install
npm install
コマンドは、先ほどのpackage.json
の内容を読んで、./node_modules
ディレクトリにインストールを粛々とやってくれます。
ちなみにnpm install
のログでエラーが出てても
Scary error messages in red may appear during install. Ignore them. The install will succeed.
インストール中に真っ赤ないかついエラーメッセージを目にするかもしれない。全部無視してくれ。きっとインストールはうまくいっている。
とのことです。
➜ angular2-quickstart ls node_modules package.json
アプリケーションの実装
アプリケーションのソースコード用のディレクトリを作ります。
mkdir app
app/app.component.js コンポーネント
コンポーネントを定義するファイルを作ります。
touch app/app.component.js
コンポーネントはAuglar2における基本的な構成要素です。Webページのパーツに対応し、ユーザにデータを表示したりユーザの操作を受け付けたりします。 コード状では、コンポーネントはビューのテンプレートを制御するクラスとして書かれます。Angularの開発ではこのコンポーネントというのをたくさん書くことになります。
ファイルを開いて以下のように書きます。
(function(app) { // (3) app.AppComponent = // (2) ng.core.Component({ // (1) selector: 'my-app', // <- CSSセレクタ。コンポーネントを挿入する先。ここではmy-appタグを指定している。 template: '<h1>My First Angular 2 App</h1>' // <- テンプレート。コンポーネントが挿入する内容。 }) .Class({ constructor: function() {} }); })(window.app || (window.app = {}));
以下、コードを内側から見ていきます。
(1) コンポーネントのスキーマ定義
ng.core.Component({ // .... }) .Class({ // .... });
ng.core
はグローバルに存在するAngularのコアの名前空間です。*2
ここでは、ng.core
名前空間のComponent
とClass
というメソッドをチェーンして呼び出すことでコンポーネントを作成しています。
通常、Angular2のアプリケーションファイルは、1つのコンポーネントをエクスポートします。
このapp/app.component.js
ではAppComponent
がエクスポートされます。
(2) エクスポート
app.AppComponent =
app
オブジェクトにコンポーネントを入れることで、グローバルな空間にエクスポートします。
より複雑なアプリケーションでは、AppComponent
の下にさらにいくつものコンポーネントがツリー状にぶら下がることになるようです。
(3) 即時関数(IIFE、Immediately Invoked Function Expression)
(function(app) { // .... })(window.app || (window.app = {}));
コードの一番外側の部分です。
app
という変数を即時関数に渡しています。
即時関数は、関数がスコープを作るJavascriptにおいてよく使われるイディオム的なスコープ作成の手法です。
app
が存在しない場合には空のオブジェクトに初期化しています。
app/main.js エントリポイントとなるファイル
次に、作成したこのコンポーネントを読み込むコードを書きます。
以下のように新しいファイルを作成し、
touch app/main.js
このファイルを開いて以下のように書きます。
(function(app) { document.addEventListener('DOMContentLoaded', function() { // (2) ng.platform.browser.bootstrap(app.AppComponent); // (1) }); })(window.app || (window.app = {}));
(1) bootstrap
Angularを起動するbootstrap
関数を呼び出しています。
呼び出しの際にルートとなるコンポーネントを教えています。今回のルートのコンポーネントは、さっき作成したAppComponent
です。
(2) bind
上記の処理を、ページの表示が終わったタイミング*3で発火するようにイベントリスナに登録しています。
index.html Angularがコンポーネントを挿しこむ場所
今まで作成したJavascriptが動作する場所を作ります。HTMLです。
touch index.html
このindex.html
はapp
配下ではなく、その上のディレクトリに作ります。この時点でファイル構成は以下のとおりです。
➜ angular2-quickstart tree | head -6 . ├── app │ ├── app.component.js │ └── main.js ├── index.html ├── node_modules
このindex.html
を開いて以下のように書きます。
<html> <head> <title>Angular 2 QuickStart</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="styles.css"> <script src="node_modules/es6-shim/es6-shim.min.js"></script> <!-- (1) ES6が使えないブラウザでES6の機能を提供するライブラリ --> <script src="node_modules/angular2/es6/dev/src/testing/shims_for_IE.js"></script> <script src="node_modules/angular2/bundles/angular2-polyfills.js"></script> <script src="node_modules/rxjs/bundles/Rx.umd.js"></script> <script src="node_modules/angular2/bundles/angular2-all.umd.js"></script> <script src='app/app.component.js'></script> <!-- (2) モジュールの読み込み --> <script src='app/main.js'></script> </head> <body> <my-app>Loading...</my-app> <!-- (3) コンポーネントが挿入される場所 --> </body> </html>
(1)
ES6の機能を提供するライブラリを読み込んでいます。
このように最新の機能が使えないブラウザに対して最新でない機能を使って同等の機能を提供することをpolyfillと言うそうです。
(2)
さっき作ったモジュールを読み込んでいます。
app/main.js
はapp/app.component.js
に依存している(利用している)ので、app/app.component.js
を先に読み込まなければいけないことに注意します。
(3)
my-app
タグです。
このmy-app
タグは、app/app.component.js
内のコンポーネント定義の際にselector
で指定されています。
これにより、Angularが、このmy-app
タグをtemplate
の内容で差し替えます。
実行する
ここまでで、必要なファイルの作成が完了したので実行します。
プロジェクトのルート(app
ディレクトリとかindex.html
を置いている場所)に移動し、以下のコマンドを叩きます。
npm start
Chromeで http://localhost:3000/ にアクセスして、My First Angular 2 App
と表示されていればうまくいっています。
index.html
ファイルは、通常Webサーバからクライアント(つまりブラウザ)に配信されるため、本来であればサーバを準備する必要があります。
しかし、サーバの準備は面倒だし、Angular自体を学習する際の本質ではなので、quickstartではlite-server
という簡易サーバを使っています。
このlite-server
は、npmで落としてきています。package.json
に依存が書かれています。
app/app.component.js
の<h1>My First Angular 2 App</h1>
を<h1>ほげほげ</h1>
とか適当に書き換えて保存します。
lite-server
が変更を検知して自動的にブラウザが読み込まれブラウザの表示がほげほげ
に変わります。
lite-server
はターミナルでCTRL + c
とかしてkillすれば落とせます。
実際のアプリケーションではJavascript内に静的に<h1>My First Angular 2 App</h1>
と書くことはあまりなく、HTMLに挿しこむデータはサーバにリクエストして取ってくるのだと思います。
感想
コードはgithubにpushしました。
Angular2自体は、内部でどう動いてるかとか気にしなければ使い方は簡単そうでした。