僕がnpm installに-gをつけないわけ

  • 76
    いいね
  • 3
    コメント
この記事は最終更新日から1年以上が経過しています。

Node.js開発に欠かせないnpm install
その中でもgulpやmochaみたいにコマンドから起動する類のものには-gオプションをつけることが多いかと思います。
ていうかサンプルとかだと普通に「-gつけてね」みたいな感じのノリです。

:npm installでググってみたら上の方に出たやつ(注:リンク先の記事ではnpm install -g gulpとなってますが、2016-04-14現在公式でnpm install -g gulp-cliが推奨されています)

しかし私は極力-gを使いたくないのです。ていうか全く使わなくていいのではとさえ思っています。
というわけで-gについて徒然なるままに心にうつりゆくよしなし事を書き綴ります。

なぜ-gが必要か

そもそもなぜ-gが必要なのでしょうか。
-gをつけないとパスが通らないからですね。
gulpで試してみましょう。

npm install gulp --save
gulp 

当然「そんなコマンド無えよ」と叱られます。
しかし、パッケージはインストールされているので、ちゃんとパスを指定してやればgulpは動くはずです。
こんな感じで

./node_modules/gulp/bin/gulp.js

一応gulpは動きますが、タスク内で相対パスを使ってたらちゃんと動くのだろうか...
それ以前にこれを毎回打ち込むのはすこぶる面倒くさい。

gulpはまだ良心的な方で、インストール時にnode_modules直下にできるディレクトリがgulpディレクトリだけで済むからどいつを起動すればいいかすぐにわかります。
browserifyをインストールしたらbrowserify〇〇というディレクトリが10個ほど出来上がってしまうため、パスを指定して起動するのも一苦労です。

それが-gつけたらどこからでもコマンド一発でよびだせるからそりゃあ便利ですよね。

ではなぜ-gを使いたくないのか

「こんなに便利だとわかってて使いたくないとか馬鹿なの?」みたいなツッコミがきそうなので、
私が考える-gを使うべきでない理由を述べます。

一言で表すならポータビリティが損なわれるからです。

ポータビリティが損なわれるってどういうこと?

-gでインストールしてると他の環境に引っ越したりコピーしたりするのが非常に面倒ということです。
自分のマシンだけで開発するならそれでも問題ありませんが、「本番環境にデプロイする」「他の人と共同で開発する」となると事態は一変します。

gitからソースを落としてきてnpm install
これでいけるはずなのになんか上手くいかない...
「しまった、あれをインストールしないと」「ああ!あれも必要だった!」という悲劇が起きかねません。

どうしてこうなった...

理由は簡単で、-gが付いていた場合例え--saveとかつけててもpackage.jsonに追記されません。
プロジェクトにではなくグローバルな領域にインストールしたのですから。
-gを外してnpm install --saveすればpackage.jsonには追記されます。
しかしそれをコマンドとして使用する旨は記載されません。

すがるような気持ちでnpm list -gとかやるとそこにはコンソールに収まらないほどのディレクトリツリー...
こうなってしまったら一つずつ確認していくしかありません。
考えたくもないですね。

しかし-gでインストールしないとgulpのような便利ツールが使えない。
どうすれば良いのか。

救世主npm run

そこで颯爽と登場するのがnpm runコマンド。
こいつはpackage.jsonのscriptsのところに記載したスクリプトを起動してくれるのですが、なんとローカルインストールしたパッケージについても自動的にパスを通してくれる優れものです。

例えば

package.json
{
  "name": "sample",
  "version": "1.0.0",
  "description": "sample",
  "main": "index.js",
  "directories": {
    "test": "tests"
  },
  "scripts": {
    "gulp": "gulp"
  },
  "author": "Mic-U",
  "license": "MIT",
  "devDependencies": {
    "gulp": "^3.9.1",
  }
}

こんな感じでpackage.jsonを書いていればnpm run gulpでgulpコマンドと同様に動作します。
そのままでnpm run gulp hogeみたいにタスクを指定することもできます。
若干打ち込むコマンドが長くなりますが、-gのリスクを考えると許容範囲ではないでしょうか。

[参考]
npm で依存もタスクも一元化する