現在、Windows / Mac ともに fnm で Node.js を管理し、パッケージマネージャは npm に統一しています。Windows 側は PowerShell で運用しています。
チームや案件で問題になりやすいのが、Node.js のバージョン差です。
- 自分の Mac では動くのに、Windows では落ちる
- Node 18 で作ったのに、別の担当者は 20 を使っている
- npm / pnpm の差で lockfile が荒れる
こうしたトラブルは、技術力の問題というより管理方法が揃っていないことが原因になりがちです。
なお、Node.js のバージョン管理ツールとしては Volta の導入も当初は検討しました。Volta はプロジェクト単位で Node と npm / yarn などを固定しやすく、チーム運用では合理的とのことです。一方で私は独りまたは少人数で開発することが多く、まずは Node 管理を軽く保てる fnm + npm に落ち着きました。
この前提で、Windows / Mac 混在でも破綻しにくい Node.js 管理方法をまとめます。
結論:揃えるべきものは3つだけ
Windows / Mac 混在環境で足並みを揃えるために、最低限決めるべきことは次の3点です。
- Node.js のバージョン
- パッケージマネージャ(npm に統一)
- lockfile(package-lock.json)の運用ルール
ここが揃えば、OS や個人の環境差によるトラブルは大幅に減ります。
Node.js の管理は fnm で統一する
fnm を使っている理由
- Windows / Mac 両方で同じ考え方で運用できる
- Node の切り替えが速い
- プロジェクト単位での管理がシンプル
余計な設定を持ち込まず、Node の管理にだけ集中できる点が実務に向いています。
Volta を選ばなかった理由(否定ではない)
Volta は、プロジェクト単位で Node と npm / yarn を pin して package.json で共有できるため、チームで切り替え忘れを減らしたい場合に有力な選択肢です(※ pnpm サポートは実験的で、環境変数の設定が必要です)。
一方で私の案件では、まず Node のバージョンが揃っていれば十分な場面が多く、ツールチェーンまで固定する運用を必須にしなくても回ります。そのため、より軽量に運用できる fnm + npm を選びました。
プロジェクト側で必ず揃える設定(ここが一番重要)
ツールの選定以上に、プロジェクト側に「揃う前提」を置くことが不可欠です。
1) .node-version をコミットする
プロジェクトルートに .node-version を置きます。
例:
20.11.1
これだけで、このプロジェクトがどの Node を使うかが明確になり、Windows / Mac を問わず同じ前提を共有できます。
2) package.json の engines を併用する
.node-version はツール向け、engines は人と CI 向けの設定です。
{
"engines": {
"node": ">=20 <21"
}
}
※ engines は想定レンジの宣言であり、設定次第では警告止まりになることがあります。強制したい場合は CI 側で担保するか、.npmrc の engine-strict などを検討してください。
3) npm に統一し、lockfile を正とする
パッケージマネージャは npm に統一します。
- lockfile は
package-lock.jsonを使用する - 必ずコミットする
- 他の lockfile は使わない
npm の運用は次のように分けています。
- 依存関係変更時:
npm install - 通常・CI:
npm ci
これだけで依存関係のブレを抑えられます。
README に書いておく最小手順(テンプレ)
環境構築は、手順に迷わない状態を作るのが理想です。
# Node.js をインストール(.node-version に合わせる)
fnm install
# 使用する Node を有効化
fnm use
# 依存関係のインストール
npm ci
# 開発
npm run dev
fnm の自動切り替え(ディレクトリ移動で .node-version / .nvmrc を見て切り替える)を使う場合は、PowerShell のプロファイル設定が必要です。設定していない場合は、上の手順どおりに fnm use を実行すれば問題ありません。
Windows / Mac 共通で動く手順にしておくと、新規参加や環境再構築がスムーズになります。
CI でも Node バージョンを揃える
ローカルと CI の Node バージョンが異なると、CI 実行時にトラブルが起きます。GitHub Actions でも .node-version を参照して揃えるように設定します。
GitHub Actions 例:
- uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: 'npm'
- run: npm ci
- run: npm test
よくある詰まりポイント
Node が二重管理になっている
- OS に直接入れた Node
- 以前使っていた別の管理ツール
これらが残っていると、node -v の結果が環境によって変わってしまいます。Node は fnm だけで管理すると決めるのが安全です。
グローバル npm 依存
グローバルに入れたツールが原因で環境差が出ることがあります。できるだけ devDependencies に寄せ、プロジェクト依存にするほうが安定します。
まとめ:Node 管理は「揃える」ための作業
Node.js 管理の目的は、環境差による手戻りを減らすことです。
- Node は fnm で管理する
.node-versionをコミットしてプロジェクトの前提を揃える- npm と
package-lock.jsonを正として運用する - CI でも
.node-versionを参照して揃える
最新かどうかよりも迷わず同じ手順で動くことを優先すると、実務でのトラブルを減らせます。