npm ci を yarn, pnpm ではどうやるのか
TL;DR
| パッケージマネージャー | コマンド |
|---|---|
| npm | npm ci |
| yarn | yarn install --frozen-lockfile |
| pnpm | pnpm i --frozen-lockfile |
npm ci とは
ci とは clean install の略です。
npm i は package.json を基にしてパッケージをインストールしますが、npm ci は package-lock.json のバージョンを基にインストールをします。
他にも以下のような特徴があります。
-
package.jsonとpackage-lock.jsonで異なる依存関係がある場合は失敗する-
npm iはpackage-lock.jsonを更新する
-
-
node_modulesディレクトリを削除してからパッケージをインストールする
そのため、CI(Continuous Integration)環境や環境構築の時は npm ci を使う方がバージョン差異が起きない便利コマンドとなっています。
これを他のパッケージマネージャーではどうするのか?
yarn
If yarn.lock is present and is enough to satisfy all the dependencies listed in package.json, the exact versions recorded in yarn.lock are installed, and yarn.lock will be unchanged. Yarn will not check for newer versions.
公式ドキュメントを読むと yarn.lock が存在する場合は yarn.lock のバージョンを基にパッケージをインストールします。
ただ、package.json と yarn.lock の依存関係で差分がある場合 yarn install だと yarn.lock を更新します。
npm ci だとエラーになるのでこの挙動も同じにするためには --frozen-lockfile をつける必要があります。
pnpm
pnpm も yarn と同様に install コマンドで pnpm-lock.yaml を基にパッケージをインストールします。
ローカル環境の時に npm ci と同じ挙動にするためには --frozen-lockfile が必要ですが、CI 環境ではデフォルトで ON になっているので明示的に指定する必要はないです。
ローカル環境か CI 環境かの判断は以下のようにしています。
exports.isCI = !!(
env.CI || // Travis CI, CircleCI, Cirrus CI, GitLab CI, Appveyor, CodeShip, dsari
env.CONTINUOUS_INTEGRATION || // Travis CI, Cirrus CI
env.BUILD_NUMBER || // Jenkins, TeamCity
env.RUN_ID || // TaskCluster, dsari
exports.name ||
false
)
Discussion