corepack v0.20.0 にて、CLI のコマンド体系が一新されて多少わかりやすくなりました (PR#291)。新しいコマンドはREADME を参照。
Node.js v14.19.0 に corepack が標準バンドルされました。
corepack がバンドルされていない Node.js v12 系は2022-04-30 に EOL を迎えるので、あと 3 ヶ月もすればアクティブな Node.js 環境には必ず corepack が揃っているという状態になりますね。引き続き experimental ステータスのままではありますが。
Node.js v16.9.0 で corepack が標準バンドルされました。まだ experimental 扱いですが。
デフォルトでは yarn も有効化されていないので、corepack enable yarnを自分で打つ必要があります。nodenv 使ってる人は rehash も忘れずに。
Node.js 本体に yarn を標準バンドルするかの議論が盛り上がったが、yarn を直接バンドルするのではなく corepack をバンドルする方向に決まったようだ。
ところで、corepack って何?
https://github.com/nodejs/corepack
元は pmm (package manager manager) という名前だった。つまり npm, yarn などパッケージマネージャーを管理するツール。
利用者がグローバルに corepack をインストールしていて、かつプロジェクト側でpackage.json にパッケージマネージャと利用バージョンを指定しておけば、指定したパッケージマネージャを自動的に使わせたり、他のパッケージマネージャを使えなくしたりできる。
もし Node.js に標準バンドルされれば、「利用者がインストールしておく」というステップが不要になり、プロジェクトの設定だけで適切なパッケージマネージャを使ってもらえることになる。
ちなみに作者のarcanis 氏は yarn のリードメンテナ。DESIGN.md によれば、npm だけが Node.js に標準バンドルされていて優遇されてるけど、他のパッケージマネージャも同等に first class citizen として扱いたい。そのために corepack によって、yarn などを使うために追加で必要なインストールなどの手間を削減するぞ、というのがモチベーションのようだ。
追記: 2022-02-03 現在、Node.js v14.19.0 以上では corepack が標準でバンドルされるようになったので、自分でインストールする必要はありません。
利用者側は npm で普通にグローバルインストールする。ただし、yarn などのバイナリを乗っ取る挙動になるので、コンフリクトしないよう yarn はあらかじめ削除しておけとのこと。
$ npm uninstall -g yarn pnpm$ npm i -g corepacknodenv を使っている場合は rehash しておくこと。ちなみにnodebrew とは相性が悪く、shim の相対パスがバグってうまく動かなかった。
package.json のpackageManager フィールドに利用するパッケージマネージャーを指定する。この最重要情報が README に書いてないのは謎。
{"packageManager":"yarn@2.0.0-rc.29"}この状態で、該当プロジェクトディレクトリでyarn コマンドを打つと、勝手に裏でyarn@2.0.0-rc.29 がインストールされてから実行される。基本はそれだけ。シンプル。
$ yarn -v2.0.0-rc.29このように透過的に動く仕組みなので、Node.js に corepack が標準バンドルされれば、確かに yarn を利用するために必要なセットアップの手間は無くなると言えそう。yarn の特定バージョン(v1 or v2 どっち?という問題もある)をバンドルするより使い勝手もメンテナンスコストも良さそうなので妥当な判断っぽい。
今度はpackageManager に npm を指定する。
{"packageManager":"npm@7.11.2"}このプロジェクト内でyarn コマンドを打つと、正しくエラーになる。
$ yarnUsage Error: This project is configured to use npmでは、npm コマンドを打つと yarn のときと同様に指定したバージョンが自動でインストールされて実行されるよね?と思うけど、されない。グローバルにインストール済みのデフォルトの npm で普通に実行されるだけ。
なぜか?corepack はデフォルトでは yarn と pnpm だけしか管理下に置いていない。npm を管理下に置くにはcorepack enable コマンドによってオプトインが必要(これはプロジェクト固有設定ではなく、一度実行するとグローバルに有効化される)。
$ corepack enable npmすると、npm コマンドで指定バージョンが自動インストールされて無事に実行されるようになる。
$ npm -v7.11.2同様に、npm を管理下に置いた状態であればpackageManager に yarn が設定されているプロジェクトでnpm コマンドを使うと正しくエラーにできる。
$ npmUsage Error: This project is configured to use yarn逆に言うと、各ユーザーがcorepack enable npm を実行しない限り、yarn なプロジェクトでnpm コマンドを使ってもエラーにならないということ。この辺り、npm も管理下に置くことの副作用やデメリットがどこまであるか分からないが、Node.js の標準バンドルになるならデフォルト有効になってた方が便利そうな気はする。
corepack enable されたパッケージマネージャーは、グローバルのバイナリを置き換えることでフックする。例えば nodenv 環境の Node.js v16 で yarn を有効化すると~/.nodenv/versions/16.0.0/bin/yarn に以下のファイルが置かれる。
#!/usr/bin/env noderequire("./corepack").runMain(["yarn","yarn",...process.argv.slice(2)]);これでフックして、プロジェクトで指定されたバージョンを~/.node/corepack/yarn/{version} から探す。無ければその場でダウンロードして展開して実行する。仕組みはシンプル。
npm i -g yarn@x.x.x に相当するデフォルトバージョンみたいなものとして、"Known Good Releases" という概念のバージョンをcorepack prepare --activate によって指定できる。
$ corepack prepare yarn@1.22.9 --activateここで指定した yarn のバージョンは~/.node/corepack/lastKnownGood.json に書き込まれ、プロジェクトによるpackageManager の指定がない場所でyarn コマンドを実行する場合に使われる。npm のバージョンも同様に管理できる。
ちなみに "Known Good Releases" が指定されていないデフォルト状態では、corepack にハードコードされた default バージョンが利用される。
Node.js に標準バンドルされれば割と便利そうなので、一気にデファクトになっていくかもしれない。
バッジを受け取った著者にはZennから現金やAmazonギフトカードが還元されます。
