Meatierのコードレビュー

#Meatierのコードレビュー
学習を兼ねてMeatierのコードを読んでいきたいと思います

Githubリポジトリ： [Meatier](https://github.com/mattkrick/meatier)

###npm run quickstartで何が起こるのか

インストール直後に実行すnpm run quickstartで何が実行されるか確認します

####package.json

```json
{

  "scripts": {
    "start": "NODE_ENV=development node ./src/server/server.babel.js",
    "prod": "NODE_ENV=production node ./src/server/server.babel.js",
    "build": "rimraf build && concurrently \"npm run build:client\" \"npm run build:server\"",
    "bs": "rimraf build && concurrently \"npm run build:client\" \"npm run build:server\" \"npm run prod\"",
    "quickstart": "rimraf build && concurrently \"npm run build:db\" \"npm run build:client\" \"npm run build:server\" \"npm run prod\"",
    "build:client": "NODE_ENV=production webpack --config ./webpack/prod.babel.js",
    "build:server": "NODE_ENV=production webpack --config ./webpack/server.babel.js",
    "build:db": "node ./src/server/database/setupDB.babel.js",
    "update:db": "node ./src/server/database/setupDB.babel.js true",
    "test": "NODE_ENV=testing ava ./src/**/__tests__/**/*.js --verbose",
    "lint": "xo --fix 'src/**/*.js' 'tests/*.js' 'webpack/*.js'",
    "profile": "NODE_ENV=production webpack --config ./webpack/prod.babel.js --profile --json > stats.json"
  },

}
```

#####利用されているnpmパッケージのメモ
- rimraf: ディレクトリごと削除 ( rm -rfのnodejs版)　[github](https://github.com/isaacs/rimraf)
- concurrently: コマンドを複数実行する際の記述が楽に　[github](https://github.com/kimmobrunfeldt/concurrently)
- rethinkdbdash


npm run quickstart　は以下を実行します

```bash
rimraf build
node ./src/server/database/setupDB.babel.js
NODE_ENV=production webpack --config ./webpack/prod.babel.js
NODE_ENV=production webpack --config ./webpack/server.babel.js
NODE_ENV=production node ./src/server/server.babel.js
```

順番に見ていきます

####rimraf build
ドキュメントルート下のbuildディレクトリを削除

####node ./src/server/database/setupDB.babel.js

setupDB.babel.jsを実行

```js
require('babel-register');
require('babel-polyfill');
require('./setupDB')(process.argv[2]);
```

babelを読み込んだ後、./setupDBからexportされた関数を実行しています
実行時に引数を与えていないので process.argv[2] は undefined です。
ちなみに　npm run update:db を実行する時は true が与えられていますね

setupDB.jsを見てみましょう

```js

import r from './rethinkdriver';

// ava is the test database
const databases = ['meatier', 'ava'];

const database = [
  {name: 'users', indices: ['email']},
  {name: 'lanes', indices: ['userId']},
  {name: 'notes', indices: ['laneId']}
];

export default async function setupDB(isUpdate = false) {
  await Promise.all(databases.map(db => ({db, isUpdate})).map(reset));
  await r.getPool().drain();
  console.log(`>>Database setup complete!`);
}

async function reset({db, isUpdate}) {
  const dbList = await r.dbList();
  if (dbList.indexOf(db) === -1) {
    console.log(`>>Creating Database: ${db}`);
    await r.dbCreate(db);
  }
  const tables = await r.db(db).tableList();
  if (!isUpdate) {
    console.log(`>>Dropping tables on: ${db}`);
    await Promise.all(tables.map(table => r.db(db).tableDrop(table)));
  }
  console.log(`>>Creating tables on: ${db}`);
  await Promise.all(database.map(table => {
    if (!isUpdate || tables.indexOf(table.name) === -1) {
      return r.db(db).tableCreate(table.name);
    }
    return Promise.resolve(false);
  }));
  console.log(`>>Adding table indices on: ${db}`);
  const tableIndicies = await Promise.all(database.map(table => {
    return r.db(db).table(table.name).indexList().run();
  }));
  await Promise.all([...database.map((table, i) => {
    const indicies = tableIndicies[i] || [];
    return table.indices.map(index => {
      if (indicies.indexOf(index) === -1) {
        return r.db(db).table(table.name).indexCreate(index).run();
      }
      return Promise.resolve(false);
    });
  })]);
  console.log(`>>Setup complete for: ${db}`);
}

```

Async/Awaitで非同期処理が書かれていますね

参考記事
[Promiseとasync-awaitの例外処理を完全に理解しよう](http://qiita.com/gaogao_9/items/40babdf63c73a491acbb)
[JavaScriptは如何にしてAsync/Awaitを獲得したのか](http://qiita.com/gaogao_9/items/5417d01b4641357900c7)

まず、importされている ./rethinkdriverを見てみます

```js
import rethinkdbdash from 'rethinkdbdash';
import {getRethinkConfig} from './getRethinkConfig';

const config = getRethinkConfig();
export default rethinkdbdash(config);
```

#####利用されているnpmパッケージのメモ
- rethinkdbdash: Node.js 用の RethinkDB ドライバー　[github](https://github.com/neumino/rethinkdbdash)

こちらはconfigをRethinkDB ドライバーに渡しているだけですね

後は、データベースとテーブルを作成しているだけですね。



####webpack --config ./webpack/prod.babel.js