動機
Node.jsには node
とターミナルで打ち込めばREPLを開始できる。
が、そこそこの規模のプロジェクトで、 rails c
感覚で使おうとすると、毎回モジュールの読み込みをするのが面倒。
Railsなら
$ rails c
pry > User.first.email
=> "hoge@example.com"
みたいになるのに、これを node
でやろうとすると
$ node
> const User = require('./models').User
> User.findOne.then(user => console.log(user.get().email))
"hoge@example.com"
という具合になる。 require...
を省きたい。
問題
Node.js にはREPLという機能があり、これを使えば実現できる。
bin/console
const replServer = require('repl').start('>>> ')
replServer.context.User = User
このようなファイルを作っておけば
$ bin/console
>>> User.findOne().then...
とできる。
ただ、ここで一つ問題がある。
REPLの履歴を呼び出せない。
普段、履歴に頼る生活をしているので、これは困る。
Node.jsのIssueにもなっているが、解決されていない。理由はちゃんと読んでいないので不明。
解決策
下記のファイルを置いてあげれば、 rails c
とほぼ同様の挙動ができる。
bin/console
#!/usr/bin/env node
const fs = require('fs')
const path = require('path')
const models = require('../api/models')
const User = models.User
const replServer = require('repl').start('>>> ')
replServer.context.User = User
const replHistoryPath = process.env.HOME + '/.node_repl_history'
fs.readFile(replHistoryPath, 'utf8', (err, data) =>
data.split('\n').forEach(command =>
replServer.history.push(command)
)
)
replServer.on('exit', () => {
fs.writeFile(replHistoryPath, replServer.history.join('\n'), err => {
console.log(err)
process.exit();
})
});
// vim:set ft=js
肝心なのは replHistoryPath
以降で、起動時に読み出しと、終了時に書き出しを行っている。
これで開発が捗りそう。