Nullable<T>

yarn と npm の栄枯盛衰

December 28, 2021

2021 年 8 月に yarn の v3 がリリースされました。2020 年の同月あたりに yarn v2 がリリースされたので、約 1 年ぶりのメジャーバージョンアップになります。 v1 → v2 のパラダイムシフトは強烈でしたが、 v2 → v3 は berry というパッケージ名は相変わらずで、 v2 の正統なバージョンアップでありちょっとだけ物足りなさを感じてます。

Get Started

なにはともあれ、とりあえずは触ってみましょうか。 Node.js ≥ 16.10 であれば、 Corepack を使って以下のコマンドで yarn v3 をインストールできます。

$ corepack enable
$ corepack prepare yarn@3.0.0 --activate
# yarn.lock や README.md が生成される
$ yarn init
# .yarn/release に yarn の binary が保存される
$ yarn set version 3.0.0 

Node Linker のデフォルトは PnP なので、 PnP に親を殺された人は yarn install する前には以下のように .yarnrc で指定しておくと良いかもしれません。ちなみに、私は PnP に親を殺されてるので PnP は無効化しておきます。 加えて、 yarnPath を指定しておく方がよいでしょう。.yarn/releases を Git Object としてコミットしておくと他の開発者が yarn を最新に保つ必要がなくなるのでオススメとドキュメントに書いてあります。

# See: https://yarnpkg.com/configuration/yarnrc#nodeLinker
nodeLinker: node-modules

# See: https://yarnpkg.com/configuration/yarnrc#yarnPath
# yarn set version 3.0.0 コマンドによって保存された binary の path を記載する
yarnPath: .yarn/releases/yarn-3.0.0.cjs

私は Zero Installs にも親を殺されてるので .yarn/cache ディレクトリも ignore しておきました。

/.yarn/*
!/.yarn/patches
!/.yarn/plugins
!/.yarn/releases
!/.yarn/sdks

# Swap the comments on the following lines if you don't wish to use zero-installs
# Documentation here: https://yarnpkg.com/features/zero-installs
#!/.yarn/cache
#/.pnp.*

とりあえずこのあたりで初期設定は完了なので、 yarn install して開発始められると思います。 PnP や Zero Installs を使いたい読者の皆さんは、親を殺されていない方の記事を見に行ってください。

New Features

さて、 yarn v3 にていくつかの機能が追加されたので、掻い摘んで見ていきましょう。

Improved Shell

yarn v2 で実装された独自のインタプリタ(@yarnpkg/shell)に新しいシンタックスが用意されました。

$ build-js & build-css &    # Background jobs
$ ls 2>/dev/null            # File descriptor redirections

環境に依存せずバックグラウンドで実行できるのは割と嬉しいですね。後者のファイルディスクリプタへのリダイレクトは「実装していなかったのか」という驚きの方が強いですね。標準エラー出力を捨てたりする機会があまりなかったので、困るようなケースとは遭遇しませんでした。

Performances

「めっちゃ早くなってんで、特定のケースで pnpm よりも早いから!」って言ってるけど、果たして…という感じです。正直に申し伝えるとパッケージマネージャーによるインストールってプロジェクトの開始やパッケージの追加・削除みたいなタイミングに限られるから費用対効果が悪く、あまりパフォーマンス改善にリソース割いてほしくないな、という気持ちです。定量的に測れるという意味で、一つの指標としてはとても良いと思うんですけどね。

ESBuild Support

Go 製の爆速ビルドツールがサポートされるようになりました。PnP 用のプラグインではあるため、親を殺されてる私にはあまり恩恵がないので割愛します。キレそう。

その他、 API 用のプライグインやリンカーの改善などがありますが、パッとしませんね

Why we use yarn

ところで、人類はなぜ yarn を使っているのか、改めて考えたいです。 yarn と npm の純粋な利用率は不明ですが、一昔前までは yarn の方が利用されていたように感じています。完全に体感ですけど。

yarnpkg/yarn と yarnpkg/berry のスター数が合計 44k で npm/npm が 17k であり、 npm/npm は 4年前に npm/cli などいくつかのリポジトリに分散されているが、全て合算しても 44k には届かないでしょうから、単純にスター数で見れば yarn の方が優勢と言えます。あまりいい指標じゃないけど。

また、少し歴史を遡ってみましょう。 yarn v1 が出たのは 2017 年 9月 であり、このとき npm は v5.4.0 でした。ほどなくして npm v6 がリリースされていますが、当時の人類は npm のインストール時間に苦しみ・悩み・打ちひしがれていたわけで「少しでも楽になりたい」そういった一心で yarn に乗り換えたという歴史があるのでしょう。一応、 npm v6 でそれなりにスピードは改善されましたが、それは人類の欲望を満たすレベルではなかったようで、 npm に人が戻ってくることはありませんでした、と。

しかし、4 年の月日が流れ、 npm も由々しき進化を遂げています。ワークスペース機能やパフォーマンスの向上など、yarn のさまざまな長所を盗んだわけです。果たして、今を生きる我々にとって yarn と npm のどちらを使えばいいのでしょうか。私、気になります!(CV: 佐藤聡美)

yarn vs npm

正直なところ、提供している機能はほとんど変わりません。

細かいところで言えば npm には resolutions の機能がなかったり(npm-force-resolutionsで同等の機能は得られる)、@yarnpkg/shell みたいに OS に依存せずシェルスクリプトが実行できるインタプリタが用意されていない( run-script-osで同等の機能は得られる )けど、致命的かと言われたらそうではないと感じてます。ちょっと前まで yarn には npx と同等の機能がありませんでしたが、yarn v2 で用意されたわけですし、時の流れは残酷なもので、機能面の差異はほとんど無くなってきています。

歴史的に yarn へ流れる元凶となったパフォーマンスについては、やはり未だに yarn の方が早いです。最も早いのは pnpm だけど。ベンチーマークは pnpm が提供するこちらがおすすめ。

ただ、冒頭にも伝えた通り、パッケージのインストールや追加のコマンドは頻繁に使うものではないでしょうから、このような比較は本質的ではないと思ってます。

機能・パフォーマンスに差異がないなら、何を考えれば良いの?って感じではありますが、一つの大きな要素として yarn が迷子になっていることがあります。yarn v2 で Zero Installs や PnP を提供しはじめましたが、周辺のエコシステムが整い切らずに右往左往してるように見えています。従来の Node Linker もサポートしたり、あらゆるユースケースに対応しようとして、強みみたいなのが薄くなっている印象です。

いっそのこと、エコシステムを丸っと請け負って、 Zero Installs や PnP に振り切ってしまった方が、このままジリ貧で進んでいくよりもいいんじゃないかと個人的に思ってます。中の人ではないので、よく知らないですけど。

npm も npm で以前にレイオフがあったりと組織面で不安なことはありますが、少なくともバックには GitHub、そしてその先には Microsoft が佇んでいるでしょうから、財源の安定性と言う意味では、この上なく強いです。

yarn と npm の比較において、パフォーマンスや機能の話の他に「npm は標準でバンドルされているんだぜ!」という論調がしばしば見受けられますが、Node.js ≥ 16.10 では Corepack 経由で簡単に yarn や pnpm を有効化できるため、そこに npm の優位性は無くなってきています。

Conclusion

yarn と npm のどっちを使えば良いんだという悩みに対する回答としては、複数人開発・個人開発のどちらにおいても長期的な目線で見れば npm で良いと思ってます。

一方で、 プロトタイプを作成したり特定のパッケージの軽い検証などについては、頻繁にパッケージのインストールや追加が発生するでしょうから、そういったケースにおいては yarn でもええ yarn と感じてます。

yarn 自体は愛着があるので、ここから Zero Installs や PnP のエコシステムを整えて、 JavaScript 界隈に新たな旋風を巻き起こすことに期待してます。

ところで、このブログは Gatsby で作られているわけですが、全くバージョンアップをしていないため、そろそろ Next.js か何かで作り直そうかしらと考えている 2021 年末です。


Written by Ryo @neer_chan

© 2018-2021 Nullable<T>