WSLでnode_modulesが混在してエラーになる原因と解決策|ELFエラー・バイナリ不一致の正体
# WSLでnode_modulesが混在してエラーになる原因と解決策|ELFエラー・バイナリ不一致の正体
結論:node_modulesはOSをまたいで使い回せない
WSL上でNode.jsプロジェクトを動かそうとしたら、突然こんなエラーが出て止まった——そんな経験はありませんか?
Error: /mnt/c/Users/uracc/Desktop/myproject/node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node: invalid ELF headerまたは、
Error: The module was compiled against a different Node.js version原因はシンプルで、node_modulesの中に入っているバイナリファイルがWindowsとLinuxで異なる形式だからです。 WindowsでインストールしたものはWindows用のバイナリ、LinuxでインストールしたものはLinux用のバイナリになります。片方の環境でインストールしたnode_modulesをもう片方の環境で使おうとすると、バイナリが「別OS用のファイルだ」と認識されてエラーになります。
解決策も明確です。問題のあるnode_modulesを削除して、実行する環境(Linux側)で再インストールする。これだけです。この記事では、なぜそうなるのかを構造から説明し、再発しない環境設計までをお伝えします。
node_modules混在エラーとは何か
「node_modulesって、コピーすれば動くんじゃないの?」と最初は思いますよね。私もそう思っていました。
なぜWindowsとLinuxでバイナリが違うのか
npmパッケージの多くは純粋なJavaScriptで書かれていますが、一部のパッケージはネイティブモジュールと呼ばれる仕組みを使っています。ネイティブモジュールとは、C/C++などで書かれた処理をNode.jsから呼び出せるようにコンパイルしたものです。画像処理・暗号化・データ圧縮など、パフォーマンスが重要な処理に使われます。
このコンパイル済みのファイルが .node という拡張子で node_modules の中に入っています。そしてコンパイルは実行するOS・CPUアーキテクチャ向けに行われます。
- Windowsでコンパイル → PE形式(Windows実行可能ファイル)
- Linuxでコンパイル → ELF形式(Linux実行可能ファイル)
この2つの形式は互換性がありません。LinuxがELFヘッダーを読もうとしてWindowsのPE形式ファイルを渡された場合、「これは読めない形式のファイルだ」と判断して invalid ELF header エラーを返します。
どのパッケージでよく起きるか
ネイティブモジュールを含む代表的なパッケージとして、以下のようなものがあります。
lightningcss(CSSパーサー・Next.jsが内部で使用)sharp(画像処理)bcrypt(パスワードハッシュ)canvas(Canvas API)esbuild(バンドラー)
Next.jsプロジェクトでこの問題に遭遇しやすいのは、lightningcss が内部依存として含まれているためです。
よくあるエラー例
実際にどんなエラーが出るのか、代表的なものを整理します。エラーメッセージで検索してここに辿り着いた方は、この中に見覚えのあるものがあると思います。
エラー① invalid ELF header
Error: /path/to/node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node: invalid ELF header最も典型的なパターンです。「ELF header」はLinuxの実行ファイル形式の識別子です。このエラーが出るということは、LinuxがELF形式を期待しているのにWindows形式(またはその逆)のファイルを渡されているということです。
エラー② exec format error
/usr/bin/env: 'node': Exec format errorまたは
Error: spawn ENOENTバイナリの形式がOSと一致せず、実行自体ができない場合に出ます。
エラー③ MODULE_NOT_FOUND(プラットフォーム固有パッケージ)
Error: Cannot find module 'lightningcss-linux-x64-gnu'npmパッケージによっては、インストール時にOSを検出して対応するバイナリだけをダウンロードします。Windowsでインストールした場合、Linux用バイナリがそもそも存在しないためこのエラーになります。
なぜ混在が起きるのか
エラーの原因はわかりました。では、なぜ「混在」という状況が生まれるのでしょうか?
WSLを使っている環境では、次のような操作の流れで混在が発生します。
パターン①:Windowsでプロジェクトを作り、WSLで動かす
- Windowsのエクスプローラーから
C:\Users\uracc\Desktop\myprojectにプロジェクトを作成 - PowerShellまたはコマンドプロンプトで
npm installを実行(Windows用バイナリがインストールされる) - WSLから
/mnt/c/Users/uracc/Desktop/myprojectでプロジェクトを実行しようとする - Linux環境がWindows用バイナリを読もうとしてエラー
パターン②:/mnt/cで作業してしまう
- WSLターミナルを開き、
cd /mnt/c/Users/uracc/Desktop/myprojectで移動 - WSL上で
npm installを実行(Linux用バイナリがインストールされる) - 後日、Windowsのコマンドプロンプトから同じフォルダで作業
- Windows環境がLinux用バイナリを読もうとしてエラー
どちらも「1つのフォルダを2つのOS環境から触った」ことが根本原因です。
実体験ログ
私がこのエラーに初めて遭遇したのは、Next.jsプロジェクトをWSLで動かそうとしたときでした。
何が起きたか
プロジェクトはもともと C:\Users\uracc\Desktop\myproject に置いていました。WSLの使い方を覚えたばかりで、「WSLからもWindowsのファイルにアクセスできるなら、そのまま使えばいいか」と思い、/mnt/c/Users/uracc/Desktop/myproject でそのまま next dev を実行しました。
すると、
Error: /mnt/c/Users/uracc/Desktop/myproject/node_modules/lightningcss-linux-x64-gnu/lightningcss.linux-x64-gnu.node: invalid ELF header
at Module._extensions..node (node:internal/modules/cjs/loader:1531:18)
at Module.load (node:internal/modules/cjs/loader:1260:32)というエラーが出て、開発サーバーが起動しませんでした。
どこで気づいたか
最初は「Next.jsのバージョンが合っていないのかな」と思い、package.json を確認したり node --version を確認したりしました。バージョン関係は問題なく、30分ほど原因がわからないまま試行錯誤しました。
エラーメッセージの「ELF」という単語で検索してみたところ、「ELFはLinuxの実行ファイル形式」という情報に行き着きました。「あ、バイナリの形式の問題か」と気づいたときは、正直ちょっと拍子抜けしました。原因がわかってしまえば単純だったのですが、その「単純な原因」に気づくまでに時間がかかりました。
解決したのは、node_modulesを削除してWSLのホームディレクトリ側(~/projects/myproject)に移動し、npm install をやり直した後です。その後はエラーなく起動しました。
解決方法
手順は決まっています。今あるnode_modulesを削除して、実行する環境でインストールし直す。これが唯一の確実な解決策です。
ステップ① node_modulesを削除する
WSLターミナルで以下を実行します。
cd /mnt/c/Users/uracc/Desktop/myproject # 現在地がここなら
rm -rf node_modules
rm -f package-lock.json # lockfileも削除する(環境依存の記録が残るため)ステップ② プロジェクトをLinux側に移動する
/mnt/c/ 上での作業を続けると同じ問題が再発します。この機会に ~/ に移動してしまいましょう。
mkdir -p ~/projects
cp -r /mnt/c/Users/uracc/Desktop/myproject ~/projects/myproject
cd ~/projects/myprojectステップ③ Linux環境でnpm installし直す
npm installこれでLinux用のバイナリが正しくインストールされます。~/ 上であれば、/mnt/cよりもインストール速度が大幅に速くなります。私の環境では700秒かかっていたものが80秒になりました。
判断基準
invalid ELF headerエラーが出た → node_modulesを削除してLinux側で再インストールCannot find module 'xxx-linux-x64-gnu'→ 同様に削除・再インストール/mnt/c/上でnpm installした覚えがある → 予防として削除・再インストールを検討
再発防止
一度解決しても、作業フローを変えないと同じ問題が再発します。私が実際に徹底するようにしたルールを2つ紹介します。
ルール① npmは1つの環境でしか実行しない
プロジェクトに対してnpm installを実行するのは、WSL(Linux)側のみにします。同じプロジェクトでWindowsのコマンドプロンプトやPowerShellからもnpm installを実行する運用は避けます。
判断基準:
- WSLターミナルから
npm installする → 問題なし - Windowsのコマンドプロンプトから
npm installする →/mnt/c/上のフォルダであれば混在が起きる
ルール② プロジェクトは ~/に置く
/mnt/c/ 上に置き続ける限り、WindowsとLinuxの両方からアクセスされるリスクが残ります。WSLで使うプロジェクトは最初から `~/projects/` に作る習慣にしておくと、この問題を根本から防げます。
# 新しいプロジェクトは常にここで作る
cd ~/projects
npx create-next-app@latest my-new-appWSLの/mnt/c問題との関係
このエラーはnode_modulesのバイナリ問題ですが、発生場所は /mnt/c/ 配下であることが多いです。この2つの問題は原因が違いますが、「/mnt/cにプロジェクトを置く」という設計が引き金になっている点は共通しています。
WSLで/mnt/cが遅い理由と解決策でも説明していますが、/mnt/c/ 配下はWindowsとLinuxのファイルシステムが交わる場所であり、I/Oコストが高いだけでなく「どちらの環境からも触れてしまう」という構造的な問題を抱えています。
問題 | 原因 | 症状
--- | --- | ---
/mnt/c遅い問題 | ファイルシステム間のI/O変換コスト | npm install・git・VSCodeが重い
バイナリ混在問題 | OSごとに異なるバイナリ形式 | ELFエラー・MODULE_NOT_FOUNDどちらも「/mnt/c/にプロジェクトを置かない」で解決します。
またWSL環境では、Claudeのedit_fileツールを使ってファイル修正を行う場合も、改行コードの混在(CRLF vs LF)が原因でexact matchエラーが発生しやすいです。環境の混在は、こういった形で連鎖的に問題を引き起こします。
また、JSONの改行エスケープ問題も環境差異と密接に関係しています。WSL環境でJSONファイルを扱う際に起きる改行コード・エスケープ問題については、「JSONで改行がそのまま書けない理由」で詳しく解説しています。
よくある質問
Q: node_modulesをコピーすれば使い回せませんか?
ネイティブモジュールを含まない純粋なJavaScriptパッケージだけで構成されているプロジェクトなら、OS間でのコピーが機能することもあります。ただし、多くの実用的なプロジェクトには何らかのネイティブモジュールが含まれています。確認するよりも、削除して再インストールする方が確実で速いです。
Q: package-lock.jsonも削除した方がいいですか?
削除することをおすすめします。package-lock.json にはインストール時のプラットフォーム情報(os・cpu フィールド)が記録されることがあります。Windows環境で生成されたlockfileをLinuxで使うと、バイナリの解決が正しく行われないケースがあります。
まとめ
WSLでnode_modulesが混在してエラーになる、という問題に心当たりはありましたか?
原因はシンプルで、WindowsとLinuxでは実行ファイルの形式が違うため、片方の環境でインストールしたバイナリはもう片方では動かない、ということです。解決策も明確で、「削除してLinux側で再インストールする」だけです。
今日できる一歩は、現在のプロジェクトが /mnt/c/ 上にないかを pwd で確認することです。もしそうなら、~/projects/ への移動を検討してみてください。バイナリ問題だけでなく、I/Oパフォーマンスも同時に改善されます。
node_modulesをどの環境に置くかは、開発環境の設計判断そのものです。何をどこに置くかの考え方を体系的に整理したい方は、bizinets.bizの判断軸ページが参考になると思います。
bizinets.biz
記事を読んで「もっと知りたい」と思ったあなたへ
bizinets.biz では、ビジネスの仕組みづくりを体系的に学べるコンテンツを用意しています。まずは一度、覗いてみてください。
bizinets.biz へ行く →