tokuhirom's Blog

jspm で angular2 を使ってみる。

jspm+systemjs を angular2 では推してるっぽいし使ってみるかとおもって使ってみるとなかなか一筋縄ではいかない。 ベータ! という感じがしてよい。

そういうわけで、jspm+systemjs でやってみた記録です。

node はすでにセットアップ済みという前提です。

npm install -g typescript jspm

として、必要なツールをインストールする。

次に jspm の初期設定をする。

$ jspm init
Package.json file does not exist, create it? [yes]:
Would you like jspm to prefix the jspm package.json properties under jspm? [yes]:
Enter server baseURL (public folder path) [./]:
Enter jspm packages folder [./jspm_packages]:
Enter config file path [./config.js]:
Configuration file config.js doesn't exist, create it? [yes]:
Enter client baseURL (public folder URL) [/]:
Do you wish to use a transpiler? [yes]:
Which ES6 transpiler would you like to use, Babel, TypeScript or Traceur? [babel]:typescript
(以下略)

なんかいろいろ聞かれてセットアップが完了する。

次に依存モジュールをインストールする。

jspm install angular2 reflect-metadata zone.js es6-shim typescript

config.js の中身を以下の様な感じにいじる。そんなに意味不明な設定はない。

System.config({
    baseURL: "/",
    defaultJSExtensions: true,
    transpiler: "typescript",
    typescriptOptions: {
        "module": "commonjs",
        "emitDecoratorMetadata": true
    },
    paths: {
        "github:*": "jspm_packages/github/*",
        "npm:*": "jspm_packages/npm/*"
    },

    packages: {
        "app": {
            "main": "main",
            "defaultExtension": "ts"
        }
    },

    map: {
        /* ここは自動生成される */
    }
});

で、app/main.ts に以下のように書く。基本的には、通常の angular2 アプリと一緒なのだが、依存を明示しないといけない点があってダサい。 この依存は config.js の中に 'meta' 項目として記載することも可能なのだが、まあ import を明示的にしておいたほうがわかりやすいだろうということで import した。

//import deps
import 'zone.js';
import 'zone.js/dist/long-stack-trace-zone';

import 'reflect-metadata';
import 'es6-shim';

// app code
import {Component} from 'angular2/core';
import {bootstrap} from "angular2/platform/browser";

@Component({
    selector: 'test-app',
    template: '<h4>Hello {{name}}</h4>'
})
class TestApp {
    name: string;

    constructor(){
        this.name = 'Angular2';
        setTimeout(() => {
        this.name = 'Angular2!!!'
        },1500);
    }
}

//start our app
bootstrap(TestApp);

最後に index.html に以下のように書く。

<html>
<head>
    <title>Demo App</title>
    <script src="jspm_packages/system.js"></script>
    <script src="config.js"></script>
</head>
<body>
    <test-app>
        Loading...
    </test-app>

    <script>
        System.import('app');
    </script>
</body>
</html>

bundle

jspm bundle-sfx --minify app

とするだけで bundle 版が作成可能。bundle-sfx で作成した場合、system.js も同梱されてるので、取り扱いが楽。

で、production 環境では以下のように、build.js だけを読めばOK.

<html>
<head>
    <title>Demo App</title>
</head>
<body>
    <test-app>
        Loading...
    </test-app>
    <script src="build.js"></script>
</body>
</html>

今後の展望

java app での良い感じの取り回しについて考えていきたい。

たとえば以下のような構成にするのが良いのではないかと考える。

src/main/java
src/main/resources/static/index.html ← build.js を読む
front/app/main.ts
front/index.html                     ← config.js 読んで、動的に処理

で、web server は file:front/,classpath:/static/ を static file として扱うようにして、gradle で jspm をキックして、build/resources/static/build.js を生成すればよい。

というところまで考えたのでよろしくお願いします。

まとめ

JS 系のツールは、なんかいろいろと設定が膨らみがちだが、jspm は最小限の設定ですむのでいい感じっぽい。 (最初 webpack でやろうと思っていたが、jspm の方が楽だった)

Java アプリとの連携については、ある程度、こんな感じでやればできるなあという感触をつかめた。

どうしてもブラウザでの確認がめんどくさいので、Ajax 通信部分のモッキング含めて、いい感じにテストできるようにしたい。そのへんもちゃんと読まないとな。 https://angular.io/docs/ts/latest/guide/testing.html

あと、本稿の内容は以下の gist の内容を参考に最新版でも動くようにしたものです。 https://gist.github.com/robwormald/429e01c6d802767441ec