0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

yarn と pnpm が混在するプロジェクトで pnpm-lock.yaml に差分が出た話

0
Posted at

忙しい人向け

yarn 経由で pnpm コマンドを実行すると、yarn のレジストリ (registry.yarnpkg.com) が npm_config_registry として引き継がれます。
この状態で pnpm install --prefer-offline を実行すると、npm_config_registryregistry.npmjs.org でないことが原因で、tarball URL が lockfile に記録されてしまいます。

解決策は --registry=https://registry.npmjs.org を明示的に指定することです。

はじめに

モノレポの一部サブパッケージを yarn から pnpm に移行する作業をしていました。
pnpm install 単体では問題なく動いていたのに、全体インストールコマンドを実行すると pnpm-lock.yaml に謎の差分が出るという問題にハマったので、原因と解決策をまとめます。

環境・構成

  • yarn v1
  • pnpm v10

モノレポのルートは yarn で管理しつつ、一部のサブパッケージだけ pnpm に移行した構成です。

/ (root)       ... yarn
client/foo/    ... yarn
client/bar/    ... yarn
client/baz/    ... pnpm  ← 移行済み

全体インストールは root の package.json にスクリプトをまとめていました。

{
  "scripts": {
    "install-prefer-offline-all": "yarn install --prefer-offline && run-s install-prefer-offline:baz ...",
    "install-prefer-offline:baz": "cd client/baz && pnpm install --prefer-offline"
  }
}

yarn run install-prefer-offline-all を実行することで、yarn 管理のパッケージも pnpm 管理のパッケージも一括インストールできる設計です。

問題: lockfile に毎回差分が出る

yarn run install-prefer-offline-all を実行すると、client/baz/pnpm-lock.yaml に以下のような差分が出ます。

-    resolution: {integrity: sha512-xxxx==}
+    resolution: {integrity: sha512-xxxx==, tarball: https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz}

tarball フィールドが追加される差分です。しかも pnpm install を単体で実行すると差分は出ません。yarn run 経由のときだけ起きます。

原因の調査

最初に疑ったこと: --prefer-offline のあるなし

pnpm 移行時は pnpm install--prefer-offline なし)で lockfile を作成していました。差分が出るのは yarn 経由の pnpm install --prefer-offline を実行したときです。

「lockfile 生成時と実行時で --prefer-offline の有無が違うのが原因では?」と思ったのですが、直接 pnpm install --prefer-offline を実行しても差分は出なかったので、--prefer-offline は関係ありませんでした。

本当の原因: yarn が npm_config_registry を書き換えていた

yarn run でスクリプトを実行すると、yarn は自身の設定を環境変数として子プロセスに注入します。
そのひとつが npm_config_registry で、yarn のデフォルトレジストリである registry.yarnpkg.com がセットされます。

# yarn run 経由で実行すると環境変数がこうなっている
npm_config_registry=https://registry.yarnpkg.com

pnpm はこの環境変数を参照するため、yarn 経由で呼ばれた pnpm は registry.yarnpkg.com からパッケージを解決しようとします。

なぜ tarball URL が lockfile に記録されるのか

詳細な仕組みは追いきれていませんが、npm_config_registryregistry.npmjs.org でない状態で pnpm install --prefer-offline を実行すると tarball URL が lockfile に記録される、という現象が確認できました。

実行方法 npm_config_registry tarball の記録
pnpm install 単体 registry.npmjs.org なし
yarn run 経由の pnpm install registry.yarnpkg.com あり(差分が出る)

これが差分の正体でした。

解決策

pnpm install--registry=https://registry.npmjs.org を明示的に追加します。

-    "install-prefer-offline:baz": "cd client/baz && pnpm install --prefer-offline",
+    "install-prefer-offline:baz": "cd client/baz && pnpm install --prefer-offline --registry=https://registry.npmjs.org",

yarn 経由で実行しても参照レジストリが registry.npmjs.org に固定されるので、lockfile に不要な tarball URL が記録されなくなります。

おわりに

  • yarn 経由で pnpm を呼ぶと npm_config_registryregistry.yarnpkg.com になる
  • pnpm はデフォルトレジストリ以外を使うと tarball URL を lockfile に記録する
  • --registry を明示指定することで回避できる

yarn と pnpm を混在させる場合、yarn が環境変数を通じて意図せず pnpm の動作に影響を与えることがあります。同じ構成で困っている方の参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?