jspmで始めるES6生活


[jspm](http://jspm.io/) は npm + bower + requirejs 的なパッケージマネージャなのだけど、標準で [traceur](https://github.com/google/traceur-compiler) または [babel](https://babeljs.io/) （init 時にどちらか選べる）がバンドルされ、[systemjs](https://github.com/systemjs/systemjs) を介して [es6-module-loader](https://github.com/ModuleLoader/es6-module-loader) も有効になるので、ES6 生活を始めるのに便利そう。話題の [Aurelia.js](http://aurelia.io/) も、ES6対応のための標準ライブラリとしてjspmを活用している。

非常に初歩の初歩の取っ掛かりだけど、[JavaScript Modules and Dependencies with jspm](http://javascriptplayground.com/blog/2014/11/js-modules-jspm-systemjs/) を参考に、会社で使っている [bacon.js](http://baconjs.github.io/) と、そのプラグインの [bacon.matchers](https://github.com/baconjs/bacon.matchers) を jspm でインストールして、ES6ベースの code から呼び出すところまでやってみた。

## jspm のインストール

``` bash
$ npm install -g jspm
```

素のまま使っていると github の API アクセス数制限に引っかかってしまうので、下記コマンドで github の API トークンを登録する。

``` bash
$ jspm registry config github
```


## デフォルトの設定でひな形を作成

``` bash
$ 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 project code folder [./]:
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) [/]:
Which ES6 transpiler would you like to use, Traceur or Babel? [traceur]:
```

差分が分かりやすいように git init しておく。

```bash
$ git init
$ echo jspm_packages > .gitignore   # jspm_packages ディレクトリを無視
$ git add .
$ git commit -m "initial commit"

```

## jQuery, lodash のインストール

jQuery は [registry](https://github.com/jspm/registry) に alias が登録されているので、下記のような簡易記法でインストールできる。

``` bash
$ jspm install jquery
```

lodash も同じように書けるけど、あえて省略しない記法でインストールしてみる。

``` bash
$ jspm install "lodash=npm:lodash"
```

package は npm または github からインストール可能。github の場合は、`github:username/repository` の書式でインストールする。

そうすると、差分はこんな感じ。

``` diff
diff --git a/config.js b/config.js
index 169c694..5308c6d 100644
--- a/config.js
+++ b/config.js
@@ -1,7 +1,22 @@
 System.config({
   "baseURL": "/",
   "paths": {
-    "*": "*.js"
+    "*": "*.js",
+    "github:*": "jspm_packages/github/*.js",
+    "npm:*": "jspm_packages/npm/*.js"
+  }
+});
+
+System.config({
+  "map": {
+    "jquery": "github:components/jquery@2.1.3",
+    "lodash": "npm:lodash@3.5.0",
+    "github:jspm/nodelibs-process@0.1.1": {
+      "process": "npm:process@0.10.1"
+    },
+    "npm:lodash@3.5.0": {
+      "process": "github:jspm/nodelibs-process@0.1.1"
+    }
   }
 });

diff --git a/package.json b/package.json
index bfaf751..f7073f1 100644
--- a/package.json
+++ b/package.json
@@ -3,6 +3,10 @@
     "directories": {
       "lib": ".",
       "packages": "jspm_packages"
+    },
+    "dependencies": {
+      "jquery": "github:components/jquery@^2.1.3",
+      "lodash": "npm:lodash@^3.5.0"
     }
   }
 }
```

jspm_packages ディレクトリには、当然、jquery と lodash がインストールされている。

ここで一旦コミットしておく。

## index.html と app.js を実装

[JavaScript Modules and Dependencies with jspm](http://javascriptplayground.com/blog/2014/11/js-modules-jspm-systemjs/) を参考に index.html と app.js を実装。

```html
<!DOCTYPE html>
<html>
  <head>
    <script src="jspm_packages/system.js"></script>
    <script src="config.js"></script>
    <script>
     System.import('./app');
    </script>
  </head>
  <body>
  </body>
</html>
```

```javascript
import $ from 'jquery';
import _ from 'lodash';

console.log("jQuery version: " + $.fn.jquery);
console.log("lodash version: " + _.VERSION);
```

この状態で、何かしらの web server でこのディレクトリを駆動する。python に慣れているので下記のようにしたけど、node でも apache でも nginx でも何でも良いです。

```bash
$ python -m SimpleHTTPServer
```

この状態で localhost:8000 にアクセスすると、 developer console に

```
jQuery version: 2.1.3
lodash version: 3.5.0
```

などと表示されます。なお、import 構文についてはまだ勉強不足なのだけど、`$` や `_` は、それでなくても何でも良い感じです。

ここで一旦 git commit.


## bacon.js, bacon.matchers をインストール

bacon.js も registry に登録されているので alias 名でインストール。

``` bash
$ jspm install baconjs
```

bacon.matchers は、現時点ではまだ registry に登録されていない（pull request 出しときました）ので、省略しない書き方で npm からインストール

```bash
$ jspm install "bacon-matchers=npm:bacon.matchers" 
```

そうするとですねー、下記のように、bacon.matchers が古いバージョンの bacon.js を参照しちゃうわけですね、はい。

```diff
diff --git a/config.js b/config.js
index 5308c6d..b77bd66 100644
--- a/config.js
+++ b/config.js
@@ -9,13 +9,59 @@ System.config({

 System.config({
   "map": {
+    "bacon-matchers": "npm:bacon.matchers@0.4.0",
+    "baconjs": "npm:baconjs@0.7.53",
     "jquery": "github:components/jquery@2.1.3",
     "lodash": "npm:lodash@3.5.0",
... （中略）
+    "npm:bacon.matchers@0.4.0": {
+      "baconjs": "npm:baconjs@0.7.6"
+    },
+    "npm:baconjs@0.7.53": {
+      "assert": "github:jspm/nodelibs-assert@0.1.0",
+      "buffer": "github:jspm/nodelibs-buffer@0.1.0",
+      "fs": "github:jspm/nodelibs-fs@0.1.2",
+      "path": "github:jspm/nodelibs-path@0.1.0",
+      "process": "github:jspm/nodelibs-process@0.1.1"
+    },
+    "npm:baconjs@0.7.6": {
+      "buffer": "github:jspm/nodelibs-buffer@0.1.0",
+      "process": "github:jspm/nodelibs-process@0.1.1"
+    },
... （中略）

diff --git a/package.json b/package.json
index f7073f1..28e3364 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,8 @@
       "packages": "jspm_packages"
     },
     "dependencies": {
+      "bacon-matchers": "npm:bacon.matchers@^0.4.0",
+      "baconjs": "npm:baconjs@^0.7.53",
       "jquery": "github:components/jquery@^2.1.3",
       "lodash": "npm:lodash@^3.5.0"
     }
```

bacon.matchers には、プラグインとしての立場（Bacon オブジェクトに追加のメソッドを付与する）的に、同じバージョンの bacon.js を参照してくれないと困るので、config.js を書き換えます。（この辺りは、もろもろ試行錯誤の末にたどり着きました）

```diff
     "npm:bacon.matchers@0.4.0": {
-      "baconjs": "npm:baconjs@0.7.6"
+      "baconjs": "npm:baconjs@0.7.53"
     },
```

## app.js から Bacon を呼び出す

最後に、app.js に Bacon 関連のロジックを追加します。こんな感じ。

```javascript
import $ from 'jquery';
import _ from 'lodash';
import Bacon from 'baconjs';
import "bacon-matchers";

console.log("jQuery version: " + $.fn.jquery);
console.log("lodash version: " + _.VERSION);

Bacon.fromArray(["Bacon","Lettus","Tomato"]).where().equalTo("Bacon").assign(console, "log");
```

先ほどと同じように web server で駆動して、ブラウザの developer console に

```
jQuery version: 2.1.3
lodash version: 3.5.0
Bacon
```

と表示されたら成功です。

## まとめ

import までしかやりませんでしたが、app.js では ES6 が書けるわけで、既存のライブラリを活用しながら ES6 を開発する環境として、申し分ないな、と思いました。production で使うためのワークフローとかは、[公式ドキュメント](https://github.com/jspm/jspm-cli/wiki)にまとまっています。