jspm で快適 javascript 生活（クライアントサイド JS の依存管理決定版）

追記
===
config.js は常に自動生成されるものだと思っていましたが、その認識は誤りだったようです。
そのため、jspm_packages 下ではなく、public ディレクトリに設置するようにしました。

はじめに
===
ぼくは Web の技術が大好き。
はじめに HTML 書いてブラウザで見たら表示されて感動したのを今でも覚えてる。
そんな調子でプログラミングの仕事について、ずっとそこらへんを書いてるけど、
最近の開発、めんどくせーこと多くないですか。

AltJS だー、React + JSX だー。ミニファイだー。依存の解決だー！

もちろん、必要なことだし、イケてるのもわかるけど、開発中に毎回 watch すんのもめんどいし...。と思っていた。

救世主 jspm
===
会社の人がなにげなく紹介していた jspm。
ビルドツールとかの「開発全体がキレイで楽になります！」っていうのが好きなので、試してみた。

結論としては、**かなりイケてる**。

- ファイル結合してない状態でブラウザ実行可能（requirejs ぽい、webpack はビルドしないとだし、多少だるい）
- 依存の解決まで面倒を見てくれ、npm や github のモジュールも利用可能（bower 的なもの。でも、bower より数倍イケてる）
- 全体的に筋がいい感じがする

最近はもっぱら webpack 使ってビルドしてたけど、もっと広い範囲をカバーしてくれており、
開発ワークフローもすごくいい感じになりそうだし筋もよさそう。乗り換える気で勉強することに決定。

jspm の紹介
===

これはなに
---
簡単にいうと bower + requirejs + gulp のようなものです。
（gulp は流石に言い過ぎ感あるかも、js のビルド部分だけです。）

- クライアントサイドで利用する ライブラリの依存解決（github, npm などのライブラリを指定可能！）
- クライアントサイド js の読み込み依存の解決
- ビルド

どうです。イケてる感じで上を解決してくれるんだったら使ってみたくなりませんか？
とりあえず、下に使い方などを書くので各自で判断して使ってみてください。
ぼくは、ちょうど新しいプロジェクトが今度あるので使ってみる気まんまんです。

インストール
---
最近のクライアントサイド開発やってるなら、node.js は導入してますよね。

```
npm install -g jspm
```

これで ```jspm``` コマンドが使えるようになりました。

プロジェクトへの組み込み
---
使い方の説明には、簡易的なディレクトリ構成の説明がある方が都合がいいので、下記の構成をご想像ください。

```
~/
  example/
    public/
      scripts/ （ここに自分が書いた js を保存するという設定にしてみます。）
      index.html
    package.json （こいつは後で生成されるので、最初は用意しなくてもよいです。）
```

とりあえず、プロジェクトで jspm を使い始めるには

```
jspm init
```

を実行します。
実行すると、様々なことを聞いてきます。

```
Package.json file does not exist, create it? [yes]: y
Whould you like jspm to prefix the jspm package.json properties under jspm? [yes]: y （※1）
Enter a name for the project (optional):
Enter baseURL (public folder) path [.]: public
Enter project code folder [public/lib]: public/scripts （お好みで）
Enter jspm packages folder [public/jspm_packages]: （お好みで）
Enter config file path [public/config.js]: public/config.js （お好みで）
Configuration file public/jspm_packages/config.js doesn't exist, create it? [yes]: y
```
> ※1: jspm は package.json に設定を保存する。その際、jspm というキーに全部入れるようにするよ？ってこと、y 安定。

こんな感じでいきましょう。するとファイルが諸々作成され下記のようになります。

```
~/
  example/
    public/
      jspm_packages/
      config.js
      index.html
    package.json
```

基本的なセットアップはこれで完了です。
試しに package.json の中をのぞいてみてください。先ほどの質問で変更したものが保存されています。

ライブラリのインストール
---
では、次に jspm を使ってライブラリをインストールします。
入れるライブラリによっては問題が起こったりもしますが、ここでは jquery と lodash を入れてみます。

```
jspm install github:components/jquery npm:lodash
```
> github から入れる場合は github:username/reponame
> npm から入れる場合は npm:package-name
> https://github.com/jspm/registry にある、registory.json に書いてあるものは指定なしで入れられます。

これで終わりです。

ライブラリの利用
---
下記のようにすると利用できます。

```html:index.html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <title>jspm で快適 javascript 生活</title>
  </head>
  <body>
    <!-- 題材が思いつかなすぎてなんだこれ感あるサンプル -->
    <div class="count">0</div>
    <button class="button">カウントアップ</button>

    <script src="jspm_packages/system.js"></script>
    <script src="config.js"></script><!-- 設定した config.js の場所を指定する -->
    <script>
      System.import('app/main'); // app/* は今回の設定では scripts/main に変換される
    </script>
  </body>
</html>
```

```js:scripts/main.js
import $ from 'jquery'
import _ from 'lodash'

var count = 0;
$('.button').click(_.debounce(() => {
  $('.count').html(++count)
}))
```
> ES6 で書いて、ビルドもなしでブラウザで動きます。便利すぎて死んでしまいそう！

こんな感じです。

おまけ
===
ついでに React + JSX を快適に書くのも紹介します。
普段なら gulp などで JSX をビルドして...ってやってると思いますが、JSX のままブラウザで実行できてしまいます。
使い方は大体上に書いてある通りなので、早足に。

```
jspm install react jsx
```

```html:index.html
<!doctype html>
<html>
  ...
  <body>
    <div id="hello-world"></div>

    <script src="jspm_packages/system.js"></script>
    <script src="config.js"></script>
    <script>
      System.import('app/main.jsx!'); // ! を付けるとプラグインが実行されます。
    </script>
  </body>
</html>
```

```js:scripts/main.jsx
import React from 'react'
import HelloWorld from 'app/ui-components/hello-world.jsx!'

React.render(<HelloWorld name="hrsh7th" />, document.getElementById('hello-world'))
```

```js:scripts/ui-components/hello-world.jsx
import React from 'react'

export default React.createClass({

  render() {
    return <div class="hello-world">Hello, {this.props.name}.</div>
  }

})
```

以上です！