ぼくのかんがえたさいきょうのES6プロジェクトテンプレート

というのを考えたので紹介します。

https://github.com/mohayonao/es6-project-boilerplate

- - -

2015.09.04 内容が古くなっていたので修正

- リンティングツールを jshint から eslint に変更
- テストでの power-assert 用のオプション指定方法の変更

## 概要
基本的にはこの記事 [ライブラリをES6で書いて公開する所から始めよう](http://efcl.info/2015/01/09/write-es6/) (必読) と同じで、それにいくつかのタスクを追加しています。やることと使用しているライブラリは以下の通りです。

- ES6のコードをES5ベースに変換する / [babel](https://babeljs.io/)
- ブラウザ用コードを生成する / [browserify](http://browserify.org/)
- ミニファイする / [UglifyJS](http://lisperator.net/uglifyjs/)
- テストする / [mocha](http://mochajs.org/), [power-assert](https://github.com/twada/power-assert)
- カバレッジレポートを作る / [isparta](https://github.com/douglasduteil/isparta)
- リンティング / [eslint](http://eslint.org/)

## ディレクトリ構成
- `build`: ブラウザ用にビルドされたコード
  - bower install されたときに読み込まれる
- `src`: ES6で書かれたコード
  - 頑張って書くのはここのコード 
- `lib`: `src` 以下を babel で変換したコード
  - npm install されたときに読み込まれる
  - Git では管理せず、npm files に含める
- `test`: ES6 + mocha + power-assertでテストを書く
- `coverage`: カバレッジレポート
  - Git では管理せず、見るだけ

インストールされたときにどのファイルが読み込まれるかというのは package.json と bower.json でコントロールします。

```json:package.json
{
  "files": [
    "package.json",
    "README.md",
    "lib"
  ]
}
```

```json:bower.json
{
  "ignore": [
    "**/.*",
    "node_modules",
    "bower_components",
    "src"
  ]
}
```

```:.gitignore
.DS_STORE
node_modules/
lib/
coverage/
```

## ビルド
### build

目的: 完成ファイルを生成する

npm 向けやブラウザ向けなど生成物が複数あるので、それぞれのタスクを分割しています。
`build` はそれらを順番に呼ぶだけです。不要なものは削ります。

```
{
  "scripts": {
    "build: "npm run build-to5 && npm run build-browser && npm run build-minify"
  }
}
```

以下、コマンドラインで書いてあるものは npm run-scripts に書いてあるものとして読んでください。

### build-to5
目的: ES6で書かれたコードをES5に変換する
使用ライブラリ: [babel](https://github.com/babel/babel)

```
babel src --out-dir lib
```

### build-browser
目的: ブラウザ向けコードを生成する
使用ライブラリ: [browserify](https://github.com/substack/node-browserify), [babelify](https://github.com/babel/babelify)

`build-to5` で生成したコードを対象に browserify しています。
babelify を使うと一気に変換できるのですが、依存モジュールが増えるのが嫌なのでこうしています。

```
browserify lib --outfile build/es6-project-boilderplate.js
```

一気にやりたい場合はこう。

```
browserify src -t babelify --outfile build/es6-project-boilderplate.js
```

スタンドアロン化 (window.ES6ProjectBoilerplate みたいなグローバル変数を定義する) が必要な場合はこうですね。

```
browserify lib --standalone ES6ProjectBoilerplate --outfile build/es6-project-boilderplate.js
```

ソースマップについては考えを保留中。

### build-minify
目的: ブラウザ用コードを小さくする
使用ライブラリ: [UglifyJS](https://github.com/mishoo/UglifyJS2)

`build-browser` で生成したコードを対象に uglify-js で圧縮しています。

```
uglifyjs build/es6-project-boilderplate.js -o build/es6-project-boilderplate.min.js
```

## テスト
目的: ちゃんと動くか確認する
使用ライブラリ: [mocha](https://github.com/mochajs/mocha), [power-assert](https://github.com/twada/power-assert)

```
mocha --compilers js:espower-babel/guess
```

テストオプションは `test/mocha.opts` に書くのが好みです。

```mohca.opts
--reporter spec
--recursive
```

こうしておくと `build-to5` などで中間ファイル(この例では `lib`)を生成せずに ES6 のコードのままテストができます。(ここでめっちゃ悩んでいたけど @t_wada さんに教えていただいて出来るようになりました)

追記(2015.09.04)：
npm-scripts と mocha.opts のオプションを変更。npm-scripts で power-assert 用のオプションを指定しています。こうすると後述のカバレッジの取得時に power-assert を使用しなくなり、実行スピードが速くなります。

## カバレッジ
目的: テストの網羅率を調べる
使用ライブラリ: [isparta](https://github.com/douglasduteil/isparta)

すごくややこしいですが、これでテキストサマリーとHTML形式のレポートが生成されます。

```
babel-node $(npm bin)/isparta cover --report text --report html _mocha
```

追記(2015.09.04):
コマンドを若干スマートに修正。

## リンティング
目的: 潜在的なバグを取り除く
使用ライブラリ: [eslint](https://github.com/eslint/eslint), [babel-eslint](https://github.com/babel/babel-eslint)

```
eslint src test
```

`.eslintrc` はこんな感じ。ルールの設定は色々好みとか事情があると思う。

```json:.eslintrc
{
  "parser": "babel-eslint",
  "env": {
    "node": true
  },
  "extends": "eslint:recommended"
}
```

`test/.eslintrc` は上記に加えてテスト用のメソッドを追加しています。

```json:test/.eslintrc
{
  "globals": {
    "describe": true,
    "it": true,
    "before": true,
    "beforeEach": true,
    "afterEach": true,
    "after": true,
  }
}
```

追記(2015.09.04):
jshint から eslint に変更。

## travis
[travis](https://travis-ci.org/repositories) でプロジェクトを有効にしておいて .travis.yml を書きます。

```yaml:.travis.yml
language: node_js
node_js:
  - "0.12"
script:
  - npm run travis
```

```
{
  "scripts": {
    "travis": "npm run lint && npm run test"
  }
}
```

## Coveralls
このボイラープレートには入れていませんが、カバレッジレポートを [Coveralls](https://coveralls.io/) で見たいという場合は `npm i --save-dev coveralls` して `.travis.yml` を以下のように書きます。

```yaml:.travis.yml
language: node_js
node_js:
  - "0.12"
env:
  global:
    - secure: `${COVERALLS_REPO_TOKEN}`
script:
  - npm run travis
after_success:
  - $(npm bin)/coveralls < ./coverage/lcov.info
```

travis 用のタスクはカバレッジレポートを生成するように変更します。

```
{
  "scripts": {
    "travis": "npm run lint && npm run cover"
  }
}
```

`COVERALLS_REPO_TOKEN` の作り方は [これ](http://mohayonao.hatenablog.com/entry/2014/08/07/102613) を参考にしてください。