Windows環境(ちなみにWindows7)で、プロジェクト(ローカル)にインストールしたnpmのモジュールを削除したい場合に、node_modules ディレクトリを一括削除とかするとファイルパス名が長すぎて削除できないモジュールが出てきたりする。
たいていは、モジュール自体の名前が長いうえに、モジュール内に別の依存系モジュールを読み込むようなやつで、特にネストが激しいのがそういうモジュールに該当する。
npmモジュールで、Windowsにて削除ができなくなったもの一覧
経験則的に以下のモジュールが削除できなくなることが多かった。
- browser-sync
- gulp-imagemin
- gulp-pleeease
- imagemin-pngcrush
- imagemin-mozjpeg
- asset-builder
特に gulp-imagemin はネストが激しいためか、ほぼ100%エクスプローラー経由での削除はできなかった。
Windowsで削除できないnpmモジュールの消し方
削除できなくなった場合の一番簡単な対応策は、途中のディレクトリを共有化して、ネットワーク越しから削除を行う方法だ。
例えば、上の例だと、imagemin-pngcrush のディレクトリが削除できなかった場合、imagemin-pngcrush ディレクトリを右クリックして「共有(H)」>「特定のユーザー…」をクリックすると、「ファイルの共有」ウィンドウが立ち上がるので、特にユーザーの追加などせずに「共有」ボタンをクリックする。
共有化されると「ユーザーのフォルダーは共有されています。」と表示されるので、個別の項目に表示されている共有化したディレクトリ名をクリックしてネットワーク越しから該当のディレクトリにアクセスする。
つまり例えば、
C:\xampp\htdocs\development_root\wp-content\themes\sage\node_modules\imagemin-pngcrush
──というパスが、共有ネットワーク越しだと、
\\{PC名}\imagemin-pngcrush
──と短縮された形でアクセスできている状態になるのだ。
これだと、OSのファイルパス文字列長の最大数制限に引っかからなくなっている可能性があり、その場合はディレクトリの削除が可能になる。
もしこれでもパスが長いと怒られるようなら、さらに下のディレクトリまで辿ってから共有化すればよい(この時、共有ネットワーク越しだと共有化ができないので、一度ローカルのエクスプローラーからアクセスし直す必要がある)。
たいていは、親モジュールの node_modules ディレクトリか、その下のモジュール群の node_modules ディレクトリあたりを共有化すれば消せるようになるだろう。
だが、何気にかなり面倒くさい…。
Windowsでのnpmモジュールの削除のベストプラクティス?
基本的に、npmモジュールを削除するのであれば、コマンドラインから npm uninstall パッケージ名 とするのが一番無難である。これだと、ファイルパスの文字列長に関わらず、依存先から綺麗に削除してくれるので。
ただ、インストールの時と同じようにnpm uninstall とパッケージ名指定しなくても package.json を読んでモジュールの一括削除とか気の利いた削除はしてくれない。やってみても、エラーになってできなかった…。モジュール指定にワイルドカードとかも使えないし、インストールしているパッケージが多いと何気に手間がかかるのだ。
なので、私的なWindowsでnpmモジュールを削除する時のベストプラクティスとしては、Windows側で node_modules ディレクトリ内の .bin ディレクトリ以外をすべて選択して一括削除を実行し、「ファイルパス長いよエラー」が出たら、それらは「スキップ」しておき、削除後に残ったモジュールのみ npm uninstall パッケージ名 で削除するというやり方だ。
しかし、これでも node_modules ディレクトリまでのパス文字列長が長かったりすると、結構な量のモジュールがスキップ対象になって残ったりする。そういう場合は、前述のフォルダの共有化で一括削除してしまった方が逆に効果的だったりする。
うーん、npmのアンインストーラーの使い勝手がもう少し良くなるといいのだがなぁ…。ま、あまり調べてないので、もしかしたら他に良いやり方があるのかもしれんが…。