my coredump

自分用の公開メモです。主にプログラムのこととか書くはず。

node.jsでコマンドを作ってコマンド名で実行させる

node.jsでコマンドっぽいものを作ったときに、できればコマンド名だけで実行できるようにしたい。 node /path/to/script.jsとかするのは面倒だしださい。

結論としてはpackage.jsonにbinプロパティを記述すれば良い。

$ mkdir hello && cd $_
$ npm init    # <- 全部yesでOK

生成されたpackage.jsonを以下のような感じに編集する。最小限な感じに色々省いた。

{
  "name": "hello",
  "version": "0.0.0",
  "description": "",
  "bin": {
    "hello": "./bin/hello"
  }
}

コマンドのコードを書く。

$ mkdir bin
$ cat <<EOF > ./bin/hello
#!/usr/bin/env node
console.log("hello command");
EOF

試しにインストールしてみる。
ちなみにnpmは公開してなくてもローカルディレクトリを指定してそこからインストールできる。
便利。

# カレントディレクトリからグローバルにインストール
$ npm install -g .

これで/usr/lib/node_modules/hello/にインストールされ/usr/bin/helloシンボリックリンクが張られる。

ちなみにnpm install helloでプロジェクトローカルにインストールしたときは、カレントディレクトリのnode_modules/helloにインストールされるとともに、node_modules/.bin/helloにhelloのシンボリックリンクが張られる。
この場合package.jsonのscriptプロパティでコマンド名だけで利用できるようになる。

ちなみにWebアプリ作るときはexpressとか使うフレームワークの作法に従えば良いし、 ライブラリを作るときはproject/lib/以下に実装書いてproject/index.jsrequireするコードを書いてた。そうするとrequire packageしたときにproject/index.jsを読んでくれる。

コマンド形式のものを作るときのノウハウが分からなかったので調べてみた次第。

ライブラリのときの話に関しては多分package.jsonで動作変えられるしもっと良い方法があるのかも。