Meatierのコードレビュー
学習を兼ねてMeatierのコードを読んでいきたいと思います
Githubリポジトリ: Meatier
npm run quickstartで何が起こるのか
インストール直後に実行すnpm run quickstartで何が実行されるか確認します
package.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パッケージのメモ
npm run quickstart は以下を実行します
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を実行
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を見てみましょう
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の例外処理を完全に理解しよう
JavaScriptは如何にしてAsync/Awaitを獲得したのか
まず、importされている ./rethinkdriverを見てみます
import rethinkdbdash from 'rethinkdbdash';
import {getRethinkConfig} from './getRethinkConfig';
const config = getRethinkConfig();
export default rethinkdbdash(config);
利用されているnpmパッケージのメモ
- rethinkdbdash: Node.js 用の RethinkDB ドライバー github
こちらはconfigをRethinkDB ドライバーに渡しているだけですね
後は、データベースとテーブルを作成しているだけですね。