npm 11.16.0でpackage-lock.jsonのresolvedが消えてた

  • npm
  • Node.js
  • CI/CD

この記事は、構成と文章の整理にAIを使っています。
あくまで読みやすくするための補助で、内容そのものをAIにすべて任せて書いているわけではありませんが、ところどころ相談しながら整えています。

CIのベースイメージをBookwormからTrixieに切り替えたら、ついでにnpmのバージョンも上がった。で、そのままCIでself-mutation(projenのlockfile更新)を走らせたら、package-lock.jsonの差分に見慣れない変化が出てきた。

何が起きたか

npm install後の差分を見ると、一部のエントリからresolvedとintegrityが消えていた。

"node_modules/projen/node_modules/@iarna/toml": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
"integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==",
"dev": true,
"inBundle": true,
"license": "ISC"
},

最初は「Trixieに変えたせいか?」「npm 11系のバグか?」と疑った。npmのバージョンは11.16.0。changelogを確認してみたけど、resolvedを消すような機能追加やフラグの変更は見当たらない。allowScriptsのopt-in policyとか、細かいfixが並んでるだけ。

切り分けてわかったこと

全部の依存で消えてるわけじゃなかった。通常の依存はちゃんと残っている。

"node_modules/@aws-sdk/credential-provider-process": {
"version": "3.972.57",
"resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.57.tgz",
"integrity": "sha512-TiVQhuU0pbhIZAUZacbPHMyzrIdiH+lnx+PMY/Pu/b93dJrq3wdZwzUJ0TPpvNxaqbHsxJvQZW3/h/beLiKq7Q==",
"license": "Apache-2.0"
}

消えているのはinBundle: trueが付いているエントリだけ。つまりbundled dependencyだ。

bundled dependencyだと何が違うのか

inBundle: trueは「このパッケージは親パッケージ(今回はprojen)のtarballに同梱されて配布される」という意味。レジストリから個別にダウンロードされることはなくて、親のtarballを展開したときにそのまま出てくる。

そう考えるとresolved(取得元URL)やintegrity(ダウンロードしたファイルの検証ハッシュ)を書くこと自体、本来意味がない。別途フェッチしていない以上、検証すべき対象そのものが存在しないから。

むしろ今までのnpmが律儀に(実質意味のない)resolved/integrityをbundled depsにも書いていた方が、実態と合っていなかったということになる。

結論

  • Trixie移行自体は無関係。たまたま同じタイミングでnpmのバージョンが上がっただけ
  • npm 11.16.0のchangelogにこの変更に関する明示的な記載はない
  • ただし挙動としては「bundled dependencyには意味のないresolved/integrityを書かなくなった」という、実態に即した方向の整理
  • npm ci/npm installとも問題なく通ることを確認済みで、実害なし

CIのlockfile差分で「知らないうちにフィールドが消えた」系のノイズを見たら、まずinBundleかどうかを疑うと早い。