まず結論
npm install は依存関係を入れながら調整するコマンド、npm ci はlockfile通りに再現するコマンドです。
ローカル開発では npm install、CIや本番ビルドでは npm ci が使われることが多いです。
npm install
npm install は、package.json を見て依存関係をインストールします。
npm install
新しいパッケージを追加する時にも使います。
npm install astro
この時、package.json と package-lock.json が更新されることがあります。
npm install は、依存関係を入れるだけでなく、必要に応じてlockfileを更新するコマンドです。
npm ci
npm ci は、CI向けのクリーンインストールです。
npm ci
特徴:
package-lock.jsonを前提にするnode_modulesを作り直すpackage.jsonとlockfileがずれていると失敗する- lockfileを書き換えない
つまり、毎回同じ依存関係を再現したい場面に向いています。
比較
| 項目 | npm install | npm ci |
|---|---|---|
| 主な用途 | ローカル開発、依存追加 | CI、本番ビルド |
| lockfile更新 | あり得る | しない |
| node_modules | 既存を利用しながら調整 | 作り直す |
| package-lock必須 | 必須ではない | 必須 |
| ずれの検出 | 調整されることがある | エラーで止まる |
CIで npm ci が好まれる理由は、再現性が高いからです。
なぜCIでは npm ci がよいのか
CIでは、開発者のPCではなく、毎回新しい環境でビルドやテストを行います。
この時に必要なのは、柔軟な更新ではなく、同じ依存関係の再現です。
repository
-> package.json
-> package-lock.json
-> npm ci
-> test/build
lockfileと違う依存関係でテストしてしまうと、ローカルとCI、本番で結果が変わることがあります。
よくあるエラー
npm ci では、次のようなエラーが出ることがあります。
package.json and package-lock.json are out of sync
これは、package.json と package-lock.json の内容が合っていないという意味です。
対応:
npm install
でlockfileを更新し、差分を確認してコミットします。
使い分け
| 場面 | 使うコマンド |
|---|---|
| 初めて依存関係を入れる | npm install |
| パッケージを追加する | npm install package-name |
| lockfileを更新する | npm install |
| CIでテストする | npm ci |
| 本番ビルドする | npm ci |
ポイント: npm ci は「速いinstall」ではなく「lockfile通りに再現するinstall」と考えると分かりやすいです。
まとめ
npm install は依存関係を入れたり更新したりするためのコマンドです。npm ci はlockfile通りにクリーンに再現するためのコマンドです。
チーム開発やCIでは、lockfileを信頼して npm ci を使うことで、環境差による不具合を減らせます。