yarnとnpmの違い【 yarn installとnpm ciの比較】
yarnを使用してプロジェクトを進めてる時に、
「あれ、npmの時はnpm install
しないでnpm ci
を使えって言われたよな、、」
と思い、さらに
「あれ、yarnの時はyarn ci
みたいなコマンド打たなくていいのかな??」
とも思ったのでメモがてら書いてみました。
yarn installを実行したとき
yarn install
を実行した場合は下記の条件分岐があります。
yarn.lockがない場合
yarn.lock
がない、つまりpackage.json
のみがプロジェクトにある場合はpackage.json
を参照してnode_modules
を作り上げます。
yarn.lockがある場合
yarn.lock
がある場合にyarn install
を実行するとpackage.json
ではなくyarn.lockを参照してnode_modules
を作り上げます。
この挙動はnpm
で言うところのnpm ci
と同じ挙動となります。
そのため、yarn.lock
があればyarn install
時にチーム内で同じバージョンが保たれるということになります。
yarn.lockがない場合の問題点
上記にもある通り、lockファイル(yarn.lock
)がない場合には毎回package.json
を参照します。
ここで、package.json
内のdependenciesやdevDependencies内にあるパッケージのバージョンをよく見てみてください。
例えば、"nuxt": "^3.1.0"
のようにバージョンの数字の手前に^
という記号が入っていたりします。
この^
というのはそのメジャーバージョン(今回だったら3)の中で最新のバージョンをインストールするという意味です。
つまり"nuxt": "^3.1.0"
と書かれている場合は^3.x.x
系の最新のバージョンをインストールすることになります。
例えば、現時点ではnuxtの最新バージョンはv3.6.5です。(2023/08/11時点)
その場合、"nuxt": "^3.1.0"
と記述があっても実際にインストールされるのは^3.x.x
系の最新である"nuxt": "3.6.5"
なんです。
そのため、yarn.lock
がリモートリポジトリに入っていないとチームメンバー内で使用しているパッケージのバージョン違いが起こる可能性があるということです。
ですので、yarn.lock
は必ずpushし共有するようにしましょう。
npmとの比較
npm install
は常にpackage.jsonを参照し、そのため開発環境間でのバージョンのずれが生じる可能性があります。これを防ぐためにnpm ci
が推奨され、これはpackage-lock.json
を参照します。一方、yarnはyarn.lock
が存在する場合、それを優先的に参照します。そのため、yarn\では
npm ci`に相当する別のコマンドを使用する必要はありません。
yarnの日本語ドキュメントの落とし穴
下記がyarnの日本語ドキュメントです。英語の公式ドキュメントと比較するとyarn.lockがある場合の記載がないのです。 これが、勘違いを生んでいると思われます。
これだけを見ると、yarn install
を実行した場合は毎回package.json
を参照するかのような記述になってます。しかし、上記にも書いたようにそのような挙動はせずにyarn.lock
があったらしっかりとyarn.lock
を参照してパッケージをインストールします。
yarn install --frozen-lockfileについて
yarnのnpm ci
に相当するコマンドと調べていると、yarn install --frozen-lockfile
というのが出てきます。
ただこれはyarn.lock
を生成しないだけで、特段npm ci
に相当するコマンドではなさそうです。(というよりyarn install
がnpm ci
の役割まで担っている。)
まとめると
yarnを使用しているプロジェクトではyarn.lock
をリモートリポジトリにアップして、メンバーはyarn install
を実行するで良さそうです。
Discussion