🌳

npmの依存関係とv7のロックファイルについて調べてみた

20 min read

はじめに

以下のURLにてnpmやTypeScriptを使ったプラグイン開発に関する記事を書いた際にnpmに関するわからなかったこと、主に「npmの依存関係とpackage-lock.json」について調べてみました。

https://zenn.dev/estra/articles/obsidian-plugin-dev_1

記載している情報は完全に正確、網羅しているわけではなく、自分のアウトプットとして作成している点をご了承ください。

そもそも

Obsidianのプラグイン開発においてGithubのリポジトリからcloneしたリポジトリで手動でビルドする必要があり、npm iで必要なパッケージがnode_modulesというディレクトリにインストールされるということは知っていたが、node_moduelsディレクトリになぜこんなにも多くのパッケージがインストールされているのか疑問だった。package.jsonファイルのdependenciesの項目に記載されているパッケージが動作に必要でdevDependenciesは開発に必要なパッケージであるということはわかったが、その2つのセクションに書いていないパッケージがnode_modulesに入っており意味がわからないというのが調査の発端。

またnpmもかなり漠然と使ってたため、良い機会なので概念や目的も色々と調べてみた。

要点

『依存関係(dependencies)』とは
プログラム内で外部ライブラリを使っていて、それが無いと動かないという状態を依存関係という。npmを導入する理由で最も多いのはこの依存関係を管理するためとのこと。

  • プロジェクトルートにあるpacakge.jsonのdependenciesに記載されているパッケージがインストールされる(場合によってはdevDependenciesも)。
  • インストールされるdependenciesに記載されているパッケージが持つ各package.jsonファイルのdependenciesに記載されているパッケージが更にインストールされる。そして、すべての依存しているパッケージがインストールされる。
  • package-lock.jsonにはインストールされたすべてのパッケージの正確なバージョン情報が記載されており、このファイルを使えば異なるマシンで異なる時間にパッケージのインストールをしても正確に同じ環境を作ることができる。
  • npmにはバージョンがあり、使用しているバージョンのpackage-lock.json構造について知る必要があり、npm v7ではpackageオブジェクトが読み取られ、dependenciesオブジェクトは無視されるため気にかける必要はない。

npmの依存関係

npm iでインストールされるパッケージ

npm iでインストールするといっても色々とパターンがあるのでそれぞれ試してみた。

  • パターン1: 最初からpackage.jsonがある状態でnpm i
    • 自分でnpm initせずにGithubのリポジトリからクローンしたものなどはpackage.jsonが最初からある状態でnpm iコマンドでインストールすると、dependenceisに書かれているパッケージ以外のパッケージがnode_modulesにインストールされた。
  • パターン2: 自分でpackage.jsonを用意してからnpm i
    • npm initでプロジェクトを初期化してpackage.jsonを用意、dependenciesに一つだけパッケージを記載してnpm iを行ってみたところ、まったく知らないパッケージがnode_modulesにインストールされた。
  • パターン3: package.jsonを用意してからnpm i パッケージ名
    • パターン2と同様にnode_modulesディレクトリに知らないパッケージがインストールされた。

どのパターンでもプロジェクトのpackage.jsonに記載されていない多くのパッケージがインストールされていた。ググって記事を漁ってみてもあまりよく分からなかったところ、以下のYoutubeの動画をみたら一発で理解することができた(npmの全貌についてもかなりわかり易く解説されていた)。

6:00~の「Dealing with npm package dependencies」のところを参照。

つまり、インストールしたいパッケージが特定の一つであってもそれを動かすためには依存しているパッケージもろもろすべてが必要であるためプロジェクトルートのpackage.jsonに記載されていないそれらをnode_modulesにインストールしていたということだった。

たとえば動画のようにnpm install chalkでchalkというパッケージ一つをインストールしてみるとnode_moduelsにはchalk以外の5つのパッケージがインストールされている。

各パッケージのディレクトリを覗いてみるとそれぞれのパッケージごとにpackage.jsonファイルが存在し、それにはdependenciesの項目に別のパッケージが記載されていた。

chalkのpackage.jsonのdependencies
"dependencies": {
	"ansi-styles": "^4.1.0",
	"supports-color": "^7.1.0"
},

chalkというパッケージはこのdependenciesに記載されているansi-styles、supports-colorというパッケージが動かすために必要ということだ。そのためnpm i chalkではchalkを実際に使うためにansi-styles、supports-colorというパッケージを追加でインストールされている。

しかし、まだ3つも知らないパッケージがnode_moduesには存在している。理由は簡単でchalkを動かすために必要な2つのパッケージにもそれぞれ動かすために必要なパッケージがあったということだ。2つのパッケージのディレクトリも覗いてみるとchalkと同様にそれぞれpacakge.jsonファイルを持ち、dependenciesを持っていることがわかった。

ansi-sytlesのpackage.jsonのdependencies
"dependencies": {
	"color-convert": "^2.0.1"
},
supports-colorのpackage.jsonのdependencies
"dependencies": {
	"has-flag": "^4.0.0"
},

よって、これら2つのパッケージを動かすためには更にcolor-convertとhas-flagというパッケージをインストールする必要があるといことがわかる。そしてそれら2つの追加パッケージのpackage.jsonもみてみるとdependenciesの項目がないので追加でインストールする必要のあるパッケージがないことがわかる。

従って、すべてのパッケージのpackage.jsonのdependenciesに記載されているパッケージがインストールされているのでこれでようやくchalkが動かすことができる。

プロジェクトフォルダをみてみると上の画像のようにあるパッケージは単独でpackage.jsonファイルを各々持ち、dependenciesに必要なパッケージがかかれている場合にはそれぞれの依存を満たすために必要なパッケージをすべてインストールする必要がある。

依存関係の把握に使えるコマンド

ここで依存関係を把握するために便利なnpmコマンドを知ることができたので以下のcowsayというパッケージを単体でインストールしてみたログを使って紹介する。

# npmのプロジェクト初期化
$ npm init -y
# package.jsonが作成される

# cowsayというパッケージをインストール
$ npm i cowsay
# 作成されたpackage.jsonをみてみる
$ cat package.json
{
  "name": "nodetest2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cowsay": "^1.5.0"
  }
}

# dependenciesにかかれている依存のみ表示
$ npm ls
nodetest2@1.0.0
└── cowsay@1.5.0

$ npm ls -a
# すべての依存関係をツリー表示
nodetest2@1.0.0
└─┬ cowsay@1.5.0
  ├── get-stdin@8.0.0
  ├─┬ string-width@2.1.1
  │ ├── is-fullwidth-code-point@2.0.0
  │ └─┬ strip-ansi@4.0.0
  │   └── ansi-regex@3.0.0
  ├── strip-final-newline@2.0.0
  └─┬ yargs@15.4.1
    ├─┬ cliui@6.0.0
    │ ├─┬ string-width@4.2.3
    │ │ ├── emoji-regex@8.0.0 deduped
    │ │ ├── is-fullwidth-code-point@3.0.0
    │ │ └── strip-ansi@6.0.1 deduped
    │ ├─┬ strip-ansi@6.0.1
    │ │ └── ansi-regex@5.0.1
    │ └─┬ wrap-ansi@6.2.0
    │   ├─┬ ansi-styles@4.3.0
    │   │ └─┬ color-convert@2.0.1
    │   │   └── color-name@1.1.4
    │   ├─┬ string-width@4.2.3
    │   │ ├── emoji-regex@8.0.0 deduped
    │   │ ├── is-fullwidth-code-point@3.0.0
    │   │ └── strip-ansi@6.0.1 deduped
    │   └─┬ strip-ansi@6.0.1
    │     └── ansi-regex@5.0.1
    ├── decamelize@1.2.0
    ├─┬ find-up@4.1.0
    │ ├─┬ locate-path@5.0.0
    │ │ └─┬ p-locate@4.1.0
    │ │   └─┬ p-limit@2.3.0
    │ │     └── p-try@2.2.0
    │ └── path-exists@4.0.0
    ├── get-caller-file@2.0.5
    ├── require-directory@2.1.1
    ├── require-main-filename@2.0.0
    ├── set-blocking@2.0.0
    ├─┬ string-width@4.2.3
    │ ├── emoji-regex@8.0.0
    │ ├── is-fullwidth-code-point@3.0.0
    │ └─┬ strip-ansi@6.0.1
    │   └── ansi-regex@5.0.1
    ├── which-module@2.0.0
    ├── y18n@4.0.3
    └─┬ yargs-parser@18.1.3
      ├── camelcase@5.3.1
      └── decamelize@1.2.0 deduped
# dedupedは重複

# explainコマンドでbottom up view(このパッケージがなぜツリーに含まれるのかを構造的に表示)
$ npm explain cowsay
cowsay@1.5.0
node_modules/cowsay
  cowsay@"^1.5.0" from the root project
$ npm explain get-stdin
get-stdin@8.0.0
node_modules/get-stdin
  get-stdin@"8.0.0" from cowsay@1.5.0
  node_modules/cowsay
    cowsay@"^1.5.0" from the root project

# strip-anisはdeduped(重複)した依存なので色々なパッケージから必要とされていることがわかる
$ npm expalin strip-ansi
strip-ansi@6.0.1
node_modules/cliui/node_modules/strip-ansi
  strip-ansi@"^6.0.0" from cliui@6.0.0
  node_modules/cliui
    cliui@"^6.0.0" from yargs@15.4.1
    node_modules/yargs
      yargs@"15.4.1" from cowsay@1.5.0
      node_modules/cowsay
        cowsay@"^1.5.0" from the root project
  strip-ansi@"^6.0.1" from string-width@4.2.3
  node_modules/cliui/node_modules/string-width
    string-width@"^4.2.0" from cliui@6.0.0
    node_modules/cliui
      cliui@"^6.0.0" from yargs@15.4.1
      node_modules/yargs
        yargs@"15.4.1" from cowsay@1.5.0
        node_modules/cowsay
          cowsay@"^1.5.0" from the root project

strip-ansi@4.0.0
node_modules/strip-ansi
  strip-ansi@"^4.0.0" from string-width@2.1.1
  node_modules/string-width
    string-width@"~2.1.1" from cowsay@1.5.0
    node_modules/cowsay
      cowsay@"^1.5.0" from the root project

strip-ansi@6.0.1
node_modules/wrap-ansi/node_modules/strip-ansi
  strip-ansi@"^6.0.0" from wrap-ansi@6.2.0
  node_modules/wrap-ansi
    wrap-ansi@"^6.2.0" from cliui@6.0.0
    node_modules/cliui
      cliui@"^6.0.0" from yargs@15.4.1
      node_modules/yargs
        yargs@"15.4.1" from cowsay@1.5.0
        node_modules/cowsay
          cowsay@"^1.5.0" from the root project
  strip-ansi@"^6.0.1" from string-width@4.2.3
  node_modules/wrap-ansi/node_modules/string-width
    string-width@"^4.1.0" from wrap-ansi@6.2.0
    node_modules/wrap-ansi
      wrap-ansi@"^6.2.0" from cliui@6.0.0
      node_modules/cliui
        cliui@"^6.0.0" from yargs@15.4.1
        node_modules/yargs
          yargs@"15.4.1" from cowsay@1.5.0
          node_modules/cowsay
            cowsay@"^1.5.0" from the root project

strip-ansi@6.0.1
node_modules/yargs/node_modules/strip-ansi
  strip-ansi@"^6.0.1" from string-width@4.2.3
  node_modules/yargs/node_modules/string-width
    string-width@"^4.2.0" from yargs@15.4.1
    node_modules/yargs
      yargs@"15.4.1" from cowsay@1.5.0
      node_modules/cowsay
        cowsay@"^1.5.0" from the root project

使用コマンド

  • npm ls
    • 依存関係をツリー構造で表示してくれるコマンド。オプション-aをつけることで完全なツリー構造表示になる。
    • 出力が多すぎるため途中のバージョン変更において-aオプションをつけないとすべてを表示しない仕様に変更された。
    • dedupedは重複しているパッケージを示す
    • dedupedは重複排除されたパッケージを示す。
  • npm explain
    • npm ls -aではルートという上層から見た構造表示であったが、このコマンドではパッケージを指定することでそのパッケージが逆になぜツリーに含まれているか、どのパッケージから必要とされているかを階層表示してくれる。
    • 重複でインストールされているバージョンの異なるパッケージについてそれぞれのバージョンがどのパッケージのdependenciesに記載されているかをルートまでさかのぼってそれぞれを表示する。

ちなみにcowsayパッケージのpackage.jsonファイルは以下

cowsayのpackage.json(一部)
"dependencies": {
  "get-stdin": "8.0.0",
  "string-width": "~2.1.1",
  "strip-final-newline": "2.0.0",
  "yargs": "15.4.1"
},
"devDependencies": {
  "@rollup/plugin-commonjs": "15.0.0",
  "@rollup/plugin-node-resolve": "9.0.0",
  "execa": "5.0.0",
  "rollup": "2.26.5",
  "rollup-plugin-string": "3.0.0",
  "tap-dot": "2.0.0",
  "tape": "5.0.1"
},

dependenciesに記載されているパッケージ(get-stdin, string-widht, strip-final-newline, yargsの4つ)はcowsayが動作する上で必要なのでこのパッケージもインストールされる。しかし、この4つのパッケージにもそれぞれpackage.jsonファイルがあり、それぞれdependenciesを持つ。つまりそれらのdependenciesも動作する上で必要なのでインストールされる。更にインストールされたパッケージも更にdependenciesを持つ、動作に必要なのでインストールされる....ということを繰り返してすべての依存関係のあるパッケージがインストールされた結果としてnode_modulesディレクトリが大きくなり、npm ls -aで表示されるような依存ツリーが出来上がる。

次のようなパッケージの依存関係をグラフ表示てくれるサービスもあるので試してみた。

https://npm.anvaka.com/#/

chalkの依存関係は比較的少ないのでかなりわかりやすい。

一方、cowsayは33個ものnodeが存在しており依存がより複雑になっていることがわかる。

ロックファイル

package.jsonファイルに記載されたdependenciesやnpm install パッケージ名でインストールしたパッケージの依存する他パッケージがインストールされるのはわかったが、node_modulesに入っている全パッケージの情報はどうやって確認するのかという疑問が立ち上がる。例えばGithubのプロジェクトでcloneしてから実際にnpm iしてみるまでインストールされるものがわからないということは無いはずだ。どんなサイズになるかもわからないし、セキュリティ的にもよろしくないのではないか。

もちろんその方法は存在しており、すべてのインストールされるべきパッケージを記載しており、依存関係をすべて把握しているのがpackage-lock.jsonファイルということになる。

ロックファイルの目的

ということで、npm v7で使用されるpackage-lock.jsonファイルの目的について公式ドキュメントから調べてみた。

https://docs.npmjs.com/cli/v7/configuring-npm/package-lock-json

package-locl.jsonファイルはnode_modulesツリーもしくはpackage.jsonファイルを変更するすべての操作対して自動的に生成されるファイルであり、後のインストールによって同一の依存ツリーを生成できるように正確なツリーを記述する。

このファイルはソースリポジトリへコミットするように意図されており、以下の様々な目的に役立つ。

  • 同一の依存関係を正確にインストールできることを保証するために依存ツリーを単一の表現として記述する
  • node_modulesについてディレクトリそのものをコミットする必要なく、推移的な状態を確認することを可能にする
  • ソースの読みやすい差分コントロールによってツリー変更の可読性を向上させる
  • 過去にインストールされたパッケージについて繰り返される冗長なメタデータ解決を省略することでインストールプロセスを最適化する
  • npm v7においてロックファイルはパッケージツリーの完全な全体図を得るための十分な情報を含んでおり、package.jsonファイルを読む必要を減らした結果、パフォーマンスが大幅に向上する

ロックファイルの大きな目的はpackage-lock.jsonファイルにすべての推移的な依存関係を含ませることで、異なる時間に異なるマシンを使ったとしてもまったく同一の依存関係を再現したインストールを保証してくれることにある。
参考: Lockfile とは?このファイルのコミットって必要? [Beginner's Series to Node.js 9/26]

pacakge.jsonだけではだめな理由

そもそものpackage.jsonではなぜ正確な依存関係をインストールできないのか。

それはセマンティックバージョニング(Semantice Versioning: semver)と呼ばれるバージョン管理番号の指定方法と関連がある。

セマンティックバージョニング(Semantic Versinoing)とは、最もポピュラーなプロジェクトの固有バージョン方法であり、この方法を使うことでソフトウェアの変更追跡を容易ににしバージョンをクリーンでシンプルに保つことができる。
参考: Semantic Versioning | Developer Experience Knowledge Base

セマンティックバージョニングではx.y.zという方法でバージョン番号を付ける(x,y,zは整数)。それぞれの数字には意味があり、次のように使う。

  • x: メジャーバージョン
    API変更等、非後方互換
  • y: マイナーバージョン
    新規機能実装、フレームワークや機能向上、後方互換
  • z: パッチバージョン
    バグフィクス、メンテンスリリース、後方互換

このセマンティックバージョニングを使ってソフトウェアのバージョン管理を行うのが一般的であり、package.jsonではこの番号をdependenciesやdevDepenendenciesにパッケージ名と共に記述する。しかし、このバージョン指定の方法によって正確な依存関係をインストールすることができなくなっている。例えば、先程のchalkのパッケージ内に含まれるpackage.jsonのdependenceisでは以下のようにセマンティックバージョニングのバージョン番号の頭にキャレット^と呼ばれる記号がついている。

chalkのpackage.jsonのdependencies
"dependencies": {
	"ansi-styles": "^4.1.0",
	"supports-color": "^7.1.0"
},

このキャレットがついたバージョン番号は「一番左側にある、ゼロではないバージョンは変えず、それ以下のバージョンが有る場合には許容してインストールする」ことを意味している。つまり、ansi-stylesというパッケージについては「4.1.0以上4.2.0未満の最新バージョンをインストールする」というバージョンの範囲を指定していることになる。したがってnpm iではこの範囲でのansi-stylesの最新バージョンをインストールする。

ある時間にインストールしたansi-sytlesのバージョンが4.1.1であったとしても、ソフトウェアの開発は時間と共に進みansi-stylesというパッケージのバージョンは進むので、別の時間インストールすると4.1.7というバージョンがインストールされることがある。このバージョンの範囲指定での最新を入れるので他の人が同じpackage.jsonファイルを使ってインストールしても異なるバージョンのパッケージ群が入ってしまう可能性が大きい。より複雑なプロジェクトになれば依存先はかなり多いため各パッケージのバージョン更新が短い間にいくつもあるかもしれない。

といことで、実際に開発の環境でインストールしたパッケージの正確なバージョン番号というものが必要になってくるわけだ。

参考

https://zenn.dev/luvmini511/articles/56bf98f0d398a5

そもそも、dependenciesバージョン範囲を指定するものであると公式ドキュメントに書いてある。これを知らなかったため、なぜnpm iで異なるバージョンを入れてしまうのかが分からなかった。といことで、公式ドキュメントを参考にしてdependenciesdevDependenciesについてもそれぞれ明確にしておくと以下のような違いがある。

  • dependencies
    • dependencies(依存関係)はパッケージ名をバージョン範囲にマップするシンプルなオブジェクトで指定される。バージョン範囲は一つ以上のスペースで区切られる記述子を持つ文字列で記述できる。dependenciesはtarballまたはgit URLでも指定することができる。
    • チルダやキャレットによるバージョン範囲の記法があるため紛らわしい。
    • The semver parser for nodeに範囲の記述方法のすべてが記載されている。
  • devDependencies
    • そのパッケージを開発・ビルドするための外部ツールやフレームワークなど、ただプログラムを実行して使いたいユーザーには必要ないパッケージ。
    • この項目にリストされているパッケージはこれが記載されているpakcage.jsonファイルがルートにある状態でnpm installまはたnpm linkコマンドを実行したとき。

https://docs.npmjs.com/cli/v7/configuring-npm/package-json#main

package-lock.jsonの構造

主要なフィールドについて同様に公式ドキュメントから抜粋して調べてみた。npm v5/v6からこのロックファイルの構造は変わったようだ。ドキュメントを読んでいると以前のバージョンではpackage.jsonpackage-lock.jsonの両方を読んでいたようだが、いまやpakage-lock.jsonが完全な依存ツリーの情報を持つようになったのでパフォーマンスが向上したとのこと。

  • name: パッケージの名前
    package.jsonのnameと一致する
  • version: package-lock.jsonのバージョン
    package.jsonのvserisionと一致する
  • lockfileVersion: 整数のバージョン番号
    • バージョン番号がない: npm v5以前の古いshrinkwarpファイルであることを示す
    • 1: npm v5またはv6で使用されているロックファイルであることを示す
    • 2: npm v7によって使用されているロックファイルであることを示し、v1のロックファイルへの後方互換性を持っている
    • 3: npm v7によって使用されているロックファイルであることを示すが、後方互換性はない。node_modules/.package-lock.jsonの隠しロックファイルに使用され、npm v6のサポートが終了しだい将来的なnpmのバージョンで使用される可能性が高い。
  • requires: 公式ドキュメントに記載なし(ブール値)
  • package: パッケージの情報を含むオブジェクトへのパッケージロケーションをマッピングするオブジェクト
    • ルートプロジェクトは""というキーでリストされており、他のパッケージはルートプロジェクトフォルダからの相対パスで記載される。
    • version: 実際にインストールされたパッケージ内部のpackage.jsonに記載されているバージョンと一致する。
    • resolved: パッケージの実際のロケーション。
      • npmレジストリから取得されている場合にはtarballへのURL
      • git依存の場合にはコミットハッシュ付きgitのフルURL
    • integrity : このロケーションに解凍された依存パッケージに対するSRI(サブリソース完全性: Standard Subresource Integrity)として使われる文字列(sha512またはsha1で暗号化されたハッシュ値)
    • bin, license, engines, dependenceis, optionalDependnecies: package.jsonに記載されているフィールドから転記。
  • dependencies: lockfileVersion: 1を使用しているnpmのバージョンをサポートするレガシーデータ。npm v7ではpacakgeセクションが存在すればこのセクションを完全に無視するが、npm v6とv7のスイッチングをサポートするためにデータを保持している。なので基本的にv7を使っていれば中身は無視してよい。
package-lock.jsonファイルの中身(chalk単体インストール)
{
  "name": "ProjectName",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "package": {
      "": { // こいつがルートプロジェクト
        "name": "ProjectName",
        "version": "1.0.0",
        "license": "ISC",
        "dependencies": {
          "chalk": "^4.1.2"
        }
      },
      // 以下インストールしたパッケージをアルファベット順ですべて記載
      "node_modules/ansi-styles": {
        "version": "4.3.0", // これが実際にインストールされたパッケージのバージョン
        "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
        "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
        "dependencies": {
          "color-convert": "^2.0.1"
        },
        "engines": {
          "node": ">=8"
        },
        "funding": {
          "url": "https://github.com/chalk/ansi-styles?sponsor=1"
        }
      },
      // 中略
      "node_modules/supports-color": {
        "version": "7.2.0",
        "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
        "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
        "dependencies": {
          "has-flag": "^4.0.0"
        },
        "engines": {
          "node": ">=8"
        }
      },
  "dependencies": {
  // npm v7ではこのセクションは基本的に無視するので省略
  // "package"と同じ様に依存ツリーについて記述されている
  }
}

隠しロックファイルについて

npm v7においては、node_modules/.package-lock.jsonという隠しロックファイルが使用されており、node_moduldesフォルダに対して繰り返される処理を避けるようにしているとのこと。このファイルには依存ツリーに関する情報が含まれており、次の条件が満たされている場合にはnode_modulesフォルダの階層全体を読み取る代わりに使用される。

この隠しロックファイルは古いバージョンのnpmからは無視されるようになっているので現在の通常ロックファイルにあるような後方互換性は含まない。よってnpm v5/v6はこのファイルを無視する。現時点ではlockfileVersionは2になっている。

.package-lock.jsonファイルの中身
{
  "name": "ProjectName",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "package": {
    "node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    // 中略
    "node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    }            
  }
}

pakcage-lock.jsonとの違いはnpm v5/v6用のフィールドとしてあった"dependencies"がなくなっているのとルートプロジェクトを示す""がなくなっている以外は同じ。

参考:

https://nitayneeman.com/posts/catching-up-with-package-lockfile-changes-in-npm-v7/

メモ

  • npmについて調べるには使用しているバージョンのnpmについての情報が必要でありバージョンが変更されたら公式ドキュメントを再び読む必要がある。
  • Youtubeの英語版の動画にはかなり分かりやすくクオリティの高いものがあるのでドキュメントだけではなく動画も調べる価値がある。

追記

npm v8について

というかいつの間にnpm CLI v8がリリースされていました。メジャーバージョンが上がったので破壊的変更があったのではないでしょうか。ドキュメントはまだないみたいですね。追って確認したいと思います。

https://github.blog/changelog/2021-10-07-npm-cli-upgraded-to-version-8/

https://github.com/npm/rfcs/issues/445

勘違いしていたこと

今回の記事を書いた後に気づいたことや、勘違いしていたことが多々あったのでそれについて別の記事にまとめました。

https://zenn.dev/estra/articles/npm-about-dependencsies

Discussion

ログインするとコメントできます