npm でコマンド登録するパッケージ作ってみた
- カテゴリ:
- JavaScript
- Webサービス
- コメント数:
- Comments: 0
◆ package.json の bin に {コマンド名: 実行するファイルのパス}
◆ js ファイルを node 実行するなら実行するファイルに "#!/usr/bin/env node" と shebang つける
◆ インストール時に作られるスクリプトが shebang に応じて変わる
◆ js ファイルを node 実行するなら実行するファイルに "#!/usr/bin/env node" と shebang つける
◆ インストール時に作られるスクリプトが shebang に応じて変わる
ブラウザと共通のライブラリ以外にも npm のメリットがあります
グローバルインストールしておけば パッケージのプログラムをコマンドとして呼び出せます
例えば eslint
とインストールした後は
コマンドラインからこう使えます
サンプルのパッケージを作ってみます
こんなフォルダ構成にします
[echo1.js]
[package.json]
1 を表示するだけの機能です
bin の中に コマンド名を key にして そのコマンドで実行するファイルのパスを value に書きます
このパッケージをグローバルでインストールします
そうすれば (Windows) だとユーザフォルダの Appdata\Roaming\npm に echo1 と echo1.cmd ファイルができています
ここに eslint など他のインストールされているコマンド一覧が並びます
nodist や nodebrew などバージョン管理ツール使ってるとそれぞれの場所にファイルが作られます
ところで コマンド名はパッケージ名以外も設定可能なので コマンド名が他のパッケージのものと重複しないように注意が必要かも
コマンドラインから実行できるようになってるので実行してみると……
echo1.js のファイルがエディタで開きました
bin で指定したファイルはそのままだとファイルが開くだけです
このままでは .js ファイルに関連づけたプログラムが立ち上がるだけです
[echo1]
[echo1.cmd]
単純に開いてるだけですね
他のファイルを見てみるとここがもっと長く色々書かれています
そのファイルの package.json を見ても bin のところは一緒です
違いは実行するファイル自体でした
echo1.js をこうします
Windows で shebang つけても意味ないように思えますが こうして再度インストールすると
[echo1]
[echo1.cmd]
実行時に shebang によって node が起動されるのではなく インストール時に shebang に応じてコマンド用のファイルの中身が変わります
なので Windows だからときにせず shebang をつけておけばいいということになります
これでコマンドラインで実行したいものも npm に置いておけば簡単に使えますね
グローバルインストールしておけば パッケージのプログラムをコマンドとして呼び出せます
例えば eslint
npm -g install eslint
とインストールした後は
eslint --fix -c eslint.config messy_code.js
コマンドラインからこう使えます
作り方
作るのは簡単で package.json の bin にコマンド名と実行するファイルのパスを書きますサンプルのパッケージを作ってみます
こんなフォルダ構成にします
-- command-sample\
-- echo1.js
-- package.json
-- echo1.js
-- package.json
[echo1.js]
console.log(1)
[package.json]
{
"name": "command-sample",
"version": "1.0.0",
"bin": {
"echo1": "./echo1.js"
}
}
"name": "command-sample",
"version": "1.0.0",
"bin": {
"echo1": "./echo1.js"
}
}
1 を表示するだけの機能です
bin の中に コマンド名を key にして そのコマンドで実行するファイルのパスを value に書きます
このパッケージをグローバルでインストールします
そうすれば (Windows) だとユーザフォルダの Appdata\Roaming\npm に echo1 と echo1.cmd ファイルができています
ここに eslint など他のインストールされているコマンド一覧が並びます
nodist や nodebrew などバージョン管理ツール使ってるとそれぞれの場所にファイルが作られます
ところで コマンド名はパッケージ名以外も設定可能なので コマンド名が他のパッケージのものと重複しないように注意が必要かも
コマンドラインから実行できるようになってるので実行してみると……
ehco1
echo1.js のファイルがエディタで開きました
bin で指定したファイルはそのままだとファイルが開くだけです
このままでは .js ファイルに関連づけたプログラムが立ち上がるだけです
JavaScript として実行させるために
Windows で出力されたファイルを見るとこうなっていました[echo1]
"$basedir/node_modules/command-sample/echo1.js" "$@"
exit $?
exit $?
[echo1.cmd]
@"%~dp0\node_modules\command-sample\echo1.js" %*
単純に開いてるだけですね
他のファイルを見てみるとここがもっと長く色々書かれています
そのファイルの package.json を見ても bin のところは一緒です
違いは実行するファイル自体でした
echo1.js をこうします
#!/usr/bin/env node
console.log(1)
console.log(1)
Windows で shebang つけても意味ないように思えますが こうして再度インストールすると
[echo1]
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/command-sample/echo1.js" "$@"
ret=$?
else
node "$basedir/node_modules/command-sample/echo1.js" "$@"
ret=$?
fi
exit $ret
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac
if [ -x "$basedir/node" ]; then
"$basedir/node" "$basedir/node_modules/command-sample/echo1.js" "$@"
ret=$?
else
node "$basedir/node_modules/command-sample/echo1.js" "$@"
ret=$?
fi
exit $ret
[echo1.cmd]
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\command-sample\echo1.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\command-sample\echo1.js" %*
)
"%~dp0\node.exe" "%~dp0\node_modules\command-sample\echo1.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\command-sample\echo1.js" %*
)
実行時に shebang によって node が起動されるのではなく インストール時に shebang に応じてコマンド用のファイルの中身が変わります
なので Windows だからときにせず shebang をつけておけばいいということになります
これでコマンドラインで実行したいものも npm に置いておけば簡単に使えますね