2015年2月27日金曜日

npm installしたパッケージの名前だけを取得する

ローカルにインストールしたパッケージの名前だけを取得したいときのコマンド。

$ npm ls --depth=0

実行すると、以下のように、トップレベルの名前だけ取得できる。
$ npm ls --depth=0
├── browser-sync@2.2.1
├── gulp@3.8.11
├── gulp-autoprefixer@2.1.0
├── gulp-concat@2.5.2
├── gulp-imagemin@2.2.1
├── gulp-less@3.0.1
├── gulp-minify-css@0.4.6
├── gulp-minify-html@1.0.0
├── gulp-newer@0.5.0
├── gulp-plumber@0.6.6
├── gulp-sass@1.3.3
├── gulp-uglify@1.1.0
├── rimraf@2.2.8
└── run-sequence@1.0.2

トップレベルだけでなく、もう一階層深く知りたいときは
$ npm ls --depth=1

つまりdepthを増やしていけばいい。


グローバルにインストールされたパッケージを取得したいときは-gを付けるだけ。
$ npm ls --depth=0 -g
/usr/local/lib
└── npm@2.5.1

MacでNode.jsとnpmをアンインストールするには

Node.jsをMacからアンインストールするには、以下のシェルスクリプトを実行する。
lsbom -f -l -s -pf /var/db/receipts/org.nodejs.pkg.bom \
| while read i; do
  sudo rm /usr/local/${i}
done
# uninstall node
sudo rm -rf /usr/local/lib/node \
     /usr/local/lib/node_modules \
     /var/db/receipts/org.nodejs.*;

# uninstall npm
sudo rm -rf ~/.npm;

# uninstall check
node -v;
npm -v;

最後にnodeやnpmコマンドを実行して失敗することを確認している。


上記のコードを、「uninstall-node.sh」などのファイル名で保存して、実行権限を付与。
$ chmod +x ./uninstall-node.sh

実行すると、Node.js、npmのアンインストールが完了する。
$ ./uninstall-node.sh


再インストールするには

公式のダウンロードサイトからpkgをダウンロードしてNode.jsを再インストールする。homebrewやnodebrewなどからインストールする方法もあるが、公式のダウンロードサイトからpkgをダウンロードしてインストールする方法の方が確実だと感じた。

再インストールが完了したら、念の為バージョン確認。
$ node -v
v0.12.0
$ npm -v
2.5.1


アンインストールに至った経緯

そもそも、Node.jsを再インストールして白紙からやり直そうと思ったのは、npm install 実行中に色々とエラーが発生したから。

例えば、gulp-sass@1.3.3をインストールでは、以下のエラーが発生。
Error: `libsass` bindings not found. Try reinstalling `node-sass`?
    at getBinding (/path/to/my/project/node_modules/gulp-sass/node_modules/node-sass/lib/index.js:21:11)
    at Object.<anonymous> (/path/to/my/project/node_modules/gulp-sass/node_modules/node-sass/lib/index.js:181:23)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/path/to/my/project/node_modules/gulp-sass/index.js:3:17)
    at Module._compile (module.js:456:26)

更に、browser-sync@2.2.1のタスク実行では、以下のエラーが発生。
dyld: Symbol not found: _node_module_register
  Referenced from: /path/to/my/project/node_modules/browser-sync/node_modules/socket.io/node_modules/engine.io/node_modules/ws/build/Release/bufferutil.node
  Expected in: dynamic lookup


stackoverflowを見ると、Node.jsのバージョンが関係しているようだったので、クリーンな状態に一旦戻してからnpm installを試してみようと。

クリーンな状態から、再度、npm installを実行すると、gulp-sassもbrowser-syncも、問題なくローカルにインストールできた。

2015年2月26日木曜日

Git - gulpのパッケージをgitで共有したくなかったら

gulp、そしてgulpで利用するパッケージだけで、かなりディレクトリ容量が膨らむ。
これをgitで共有するのは嫌だなあと思って試行錯誤。

とりあえず、グローバルとローカルの両方にgulpをインストールするのではなく、グローバルだけにできないかと思ったが、逆(ローカルのみインストールする)はあっても、グローバルのみで動かす設定は発見できず。

gulp.jsのフローを見る限り、ローカルへのインストールは必須のようだし。
if (!env.modulePath) {
    gutil.log(
      chalk.red('Local gulp not found in'),
      chalk.magenta(tildify(env.cwd))
    );
    gutil.log(chalk.red('Try running: npm install gulp'));
    process.exit(1);
  }

このフローの通り、ローカルにgulpがインストールされていないと、gulpの実行はできない。
[13:20:52] Local gulp not found in ~/git/プロジェクト名
[13:20:52] Try running: npm install gulp


gulpが、グローバルとローカルとの、両方でインストールが必須なのには構造的な理由がある。

グローバルにインストールされたgulpは、ローカルにインストールされたgulpを実行するためのもの。このグローバルとローカルの2つのモジュールの中身は完全に同じもので、まったく同じモジュールをグローバルとローカルにインストールすることになる。

gulpコマンドが実行されると、gulp.jsのrequireで、ローカルのgulpがインポートされる。

そして、実際の処理(gulpfile.jsに書かれたタスク)はrequireされたローカルのgulpモジュールが全て行う。つまり、gulpは、自分自身が自分自身と同じモジュールをrequireして使うという仕組みで動いている。


では、ローカルへのインストールは仕方がないとしても、gitで共有したくない問題はどうにかできないかと思ったら、

gitなどでプロジェクト共有している場合、この node_modules を共有していると結構重かったりしますし、 package.json が共有されていたらあとで $ npm install をしたら必要なものが入ってくるため、 node_modules のディレクトリの共有は不要です。
Node.js 製の タスクランナー gulp.js を使ってみる - HAM MEDIA MEMO


ハッ!その手があったか!思わずポンと手を打ってしまった。


.gitignoreでnode_modulesをignoreすればいいじゃないですか。


gitからクローンした際は、npm installすればパッケージはインストールされるんだし。


ですよねぇ。これって常識だったのかしら。


追記

.gitignoreのサンプルは以下。一行だけだけれど。

/node_modules/

上記内容をプロジェクト直下にファイル名「.gitignore」で保存。
「node_modules」の前の/で、プロジェクトと同階層であることを明示。
「node_modules」の後の/で、ディレクトリであることを明示。

つまり、「/node_modules/」で、プロジェクト直下のnode_modulesディレクトリを無視する、という設定になる。