npm 経由で scripts のコマンドを実行すると $(npm bin) が PATH に追加されるらしい
package.json の scripts のところには $(npm bin)/mocha のようにローカルの mocha を明示的に指定しないといけないのかと思いきや、$(npm bin) が勝手に PATH に追加されるみたいです。
なので、mocha と記述するだけでローカルに mocha が存在すればそちらが使われます。
実際に $PATH の値を見てみます。
% cd /tmp/
% npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sane defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install <pkg> --save` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
name: (tmp)
version: (0.0.0)
description:
entry point: (index.js)
test command: echo $PATH
git repository:
keywords:
author:
license: (ISC)
About to write to /private/tmp/package.json:
{
"name": "tmp",
"version": "0.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo $PATH"
},
"author": "",
"license": "ISC"
}
Is this ok? (yes) yes
% npm test | sed "s|$HOME|\$HOME|g"
> tmp@0.0.0 test /private/tmp
> echo $PATH
/usr/local/Cellar/node/0.10.24/lib/node_modules/npm/bin/node-gyp-bin:/private/tmp/node_modules/.bin:/usr/local/Cellar/node/0.10.24/bin:$HOME/.rbenv/shims:$HOME/local/bin:/usr/local/share/npm/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
% echo $PATH | sed "s|$HOME|\$HOME|g"
$HOME/.rbenv/shims:$HOME/local/bin:/usr/local/share/npm/bin:/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin
上記の例では npm test で echo $PATH を実行するようにしています。
元の $PATH と比べると /usr/local/Cellar/node/0.10.24/lib/node_modules/npm/bin/node-gyp-bin:/private/tmp/node_modules/.bin:/usr/local/Cellar/node/0.10.24/bin が追加されていることがわかります。
パスの追加は npm の utils/lifecycle.js で行われているようです。
cf. https://github.com/joyent/node/blob/v0.10.24-release/deps/npm/lib/utils/lifecycle.js#L69-L90
なので、require(“./utils/lifecycle.js”) を実行している buiild, install, publish, restart, run-script, start, test, unbuild, update コマンド経由の場合はローカルのパッケージが優先されそうです。
というのを次の記事を読んで知ったんですが、割りと知られてる話なんですかね?
Executing A Project-Specific Node/NPM Package A-la “bundle exec” | ThoughtStream.new :derick_bailey