at backyard

Color my life with the chaos of trouble.

ネットワークがない環境で、擬似的にnpmでパッケージをglobal installしたことにして作業することは可能か?

"npm install -g {package}"がしていること

実現させたいこと

ネットワークがない環境で(npm install -g {package}ができない)、npm install -g {package}した時と同じような状態にしたい。

例えば、npm install -g webpackは出来ないが、webpackのモジュール自体はあるとする。
そのwebpackをos側の環境変数を変更することはせず、npmの仕組みの中だけでwebpack自体にpathを通してwebpackと打って実行できるようにすることは可能か?を検証したい。
(書いていてややこしいし、そもそもそんな状況どうなの??というツッコミが入りそうなことも承知の上でございます。。。)

環境

Windowsマシン(現在はまだ未検証)macマシンにて検証する。
まずはmacマシンで検証してみて可能そうであれば、windowsマシンでも検証していく。

npm install -gで格納される場所は?

下記のコマンドで調べることができる。

npm root -g
/Users/{username}/.nvm/versions/node/v6.11.2/lib/node_modules

自身のmacマシンの場合、.nvm使って入れているので、このような箇所になっています。

で、この中はどうなっているかというと、

$ls /Users/{username}/.nvm/versions/node/v6.11.2/lib/node_modules
npm/  yarn/

このようになっています。
(私は普段はyarnを使っているため、npmでglobal installしたものはyarnだけという状態となっています。)

ここに例えばwebpackのディレクトリをそのままぶち込んで動いたら、実現させたいことは一応できるということになりますかね。
やってみます。

検証

適当なディレクトリを作り、その中で下記のコマンドを実行してみます。
(なんとなくwebpackで検証してみます)

$npm intall webpack

げげ、ためしにwebpackにしてみたら、ディレクトリの数がこんなに、、、↓
さすがボリュームありますね。

$ls -1 node_modules/ | wc -l
235

それは置いておいて、、、 これで普通にローカルインストールしたwebpackを上にnpm root -gで表示されるnode_modules上に配置しても認識してくれません。

$webpack
command not found: webpack

という感じに表示されます。当然といえば当然ですが、、、

$which npm
/Users/{username}/.nvm/versions/node/v6.11.2/bin/npm

npmの実行パスを確認してみると、上記のようになっており、 このbin配下には同じようにglobal install済みのyarnのシンボリックリンクも配置されていました。

$ls /Users/{username}/.nvm/versions/node/v6.11.2/bin | grep yarn
yarn@
yarnpkg@

ということは、、、ここにwebpackのシンボリックリンクをセットすればそれで行けてしまうのでしょうか?
試してみます。

# bin配下にcdした上でのコマンド↓
$ln -s ../lib/node_modules/webpack/bin/webpack.js webpack

$ls webpack
webpack@

では、これでコマンドが打てるかをチェックしてみましょう。

$webpack -v
3.10.0

打てましたね!
というわけで、npm install -g {package}を行うと、

  1. npm root -gで表示されるnode_modules配下にパッケージをインストール
  2. npm側のbin配下に実行用のシンボリックリンクを貼る

という2つの処理が行われるようです。

他にも実際は処理が行われているかもしれませんが、コマンドを打てるようにするための処理としては上記2工程かと思われます。
(もし間違い等ありましたらコメントやツイッターなどからご指摘いただけたら幸いです)

このあと、windowsでも試してみようと思いますが、なかなか疲れてきたので、一旦ここまでとします。