CLOVER🍀

That was when it all began.

npmでプロジェクトの依存関係の確認や、依存パッケージのバージョン確認などを行ってみる

これは、なにをしたくて書いたもの?

以前、npm install(npm i)で使うバージョンについて調べてみました。

npm installなどで使うバージョンがよくわからなかったので、調べてみました - CLOVER🍀

なのですが。npmプロジェクトが依存しているパッケージを表示したり、より新しいバージョンがリリースされているかどうかなどはどうやって
確認したらいいのかなと思って調べてみると。

npmコマンドでできそうだったので、まとめておくことにします。

結論を言うと、npm ls、npm outdated、npm updateなどを使うと良さそうです。

環境

今回の環境は、こちら。

$ node --version
v16.18.1


$ npm --version
8.19.2

準備

準備として、npmプロジェクトを作成して現時点では少し古いパッケージを依存関係に追加してみます。

$ npm init -y


$ npm i express@4.17.0
$ npm i winston@3.8.0
$ npm i -D @types/node@16.18.0
$ npm i -D typescript@4.8.2

package.jsonの依存関係は、このようになりました。

  "dependencies": {
    "express": "^4.17.0",
    "winston": "^3.8.0"
  },
  "devDependencies": {
    "@types/node": "^16.18.0",
    "typescript": "^4.8.2"
  }

npmプロジェクトの依存関係を表示する

npmプロジェクトが依存しているパッケージを表示するには、npm ls(npm list)を使うと良さそうです。

This command will print to stdout all the versions of packages that are installed, as well as their dependencies when --all is specified, in a tree structure.

npm-ls | npm Docs

インストールされている依存関係を表示してくれるコマンドのようです。

実行してみます。

$ npm ls
npm-dependencies@1.0.0 /path/to/my-npm-project
├── @types/node@16.18.0
├── express@4.17.0
├── typescript@4.8.2
└── winston@3.8.0

現在のプロジェクトの依存関係が表示されました。

パッケージを直接指定することもできます。

$ npm ls express
npm-dependencies@1.0.0 /path/to/my-npm-project
└── express@4.17.0

デフォルトだと1階層しか表示しないようなので、依存しているパッケージが推移的に他のパッケージに依存している場合を表示するような
ケースでは、--depthオプションを使います。

2階層まで表示してみます。

$ npm ls --depth 2
npm-dependencies@1.0.0 /path/to/my-npm-project
├── @types/node@16.18.0
├─┬ express@4.17.0
│ ├─┬ accepts@1.3.8
│ │ ├── mime-types@2.1.35
│ │ └── negotiator@0.6.3
│ ├── array-flatten@1.1.1
│ ├─┬ body-parser@1.19.0
│ │ ├── bytes@3.1.0
│ │ ├── content-type@1.0.4 deduped
│ │ ├── debug@2.6.9 deduped
│ │ ├── depd@1.1.2 deduped
│ │ ├── http-errors@1.7.2
│ │ ├── iconv-lite@0.4.24
│ │ ├── on-finished@2.3.0 deduped
│ │ ├── qs@6.7.0 deduped
│ │ ├── raw-body@2.4.0
│ │ └── type-is@1.6.18 deduped
│ ├─┬ content-disposition@0.5.3
│ │ └── safe-buffer@5.1.2 deduped

〜省略〜

デフォルトでは、--depthに1が指定された状態で実行しているようです。

全階層を表示する場合は、--allオプションを使います。

$ npm ls --all
npm-dependencies@1.0.0 /path/to/my-npm-project
├── @types/node@16.18.0
├─┬ express@4.17.0
│ ├─┬ accepts@1.3.8
│ │ ├─┬ mime-types@2.1.35
│ │ │ └── mime-db@1.52.0
│ │ └── negotiator@0.6.3
│ ├── array-flatten@1.1.1
│ ├─┬ body-parser@1.19.0
│ │ ├── bytes@3.1.0
│ │ ├── content-type@1.0.4 deduped
│ │ ├── debug@2.6.9 deduped
│ │ ├── depd@1.1.2 deduped
│ │ ├─┬ http-errors@1.7.2
│ │ │ ├── depd@1.1.2 deduped
│ │ │ ├── inherits@2.0.3 deduped
│ │ │ ├── setprototypeof@1.1.1 deduped
│ │ │ ├── statuses@1.5.0 deduped
│ │ │ └── toidentifier@1.0.0
│ │ ├─┬ iconv-lite@0.4.24
│ │ │ └── safer-buffer@2.1.2
│ │ ├── on-finished@2.3.0 deduped
│ │ ├── qs@6.7.0 deduped

〜省略〜

重複しているものは、dedupedが付いているみたいですね。

新しいバージョンのパッケージがリリースされているかどうか確認する

現在のプロジェクトが依存しているnpmパッケージの中に、より新しいバージョンのものがリリースされているかどうかを確認するには
npm outdatedを使用します。

npm-outdated | npm Docs

実行してみます。

$ npm outdated
Package      Current   Wanted   Latest  Location                  Depended by
@types/node  16.18.0  16.18.3  18.11.9  node_modules/@types/node  npm-dependencies
express       4.17.0   4.18.2   4.18.2  node_modules/express      npm-dependencies
typescript     4.8.2    4.9.3    4.9.3  node_modules/typescript   npm-dependencies
winston        3.8.0    3.8.2    3.8.2  node_modules/winston      npm-dependencies

「Current」は現在のバージョンです。「Wanted」は、package.jsonで指定されたsemverの範囲を満たすもので最も新しいバージョンを
表示します。「Latest」はパッケージの最新のバージョンですね。

「Current」と「Latest」が一致している場合は、結果に表示されないようです。

今回、意図的に少し古いパッケージをインストールしていますが、ほとんどのものは「Wanted」と「Latest」が一致しています。
@types/nodeのみ、メジャーバージョンが異なるのでv16の範囲が「Wanted」となり、「Latest」と差が出ています。

  "dependencies": {
    "express": "^4.17.0",
    "winston": "^3.8.0"
  },
  "devDependencies": {
    "@types/node": "^16.18.0",
    "typescript": "^4.8.2"
  }

依存しているパッケージを新しいバージョンに更新する

npm outdatedで新しいバージョンのパッケージがリリースされていることを確認できたら、アップデートを検討するわけですが。

これは、npm updateで行えるようです。

npm-update | npm Docs

npm updateでは、パッケージの最新版またはsemverを満たす範囲でパッケージをアップデートします。

This command will update all the packages listed to the latest version (specified by the tag config), respecting the semver constraints of both your package and its dependencies (if they also require the same package).

不足しているパッケージがある場合は、同時に追加してくれるようです。

試してみましょう。npm outdatedの結果は以下でした。

$ npm outdated
Package      Current   Wanted   Latest  Location                  Depended by
@types/node  16.18.0  16.18.3  18.11.9  node_modules/@types/node  npm-dependencies
express       4.17.0   4.18.2   4.18.2  node_modules/express      npm-dependencies
typescript     4.8.2    4.9.3    4.9.3  node_modules/typescript   npm-dependencies
winston        3.8.0    3.8.2    3.8.2  node_modules/winston      npm-dependencies

最初にどれくらいの変更量があるのかを確認してみます。これには--dry-runオプションを使います。

$ npm update --dry-run

added 7 packages, removed 3 packages, and changed 21 packages in 757ms

8 packages are looking for funding
  run `npm fund` for details

あんまりよくわかりませんが…。

では、更新してみます。

$ npm update

added 7 packages, removed 1 package, changed 23 packages, and audited 87 packages in 5s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

npm lsの結果。

$ npm ls
npm-dependencies@1.0.0 /path/to/my-npm-project
├── @types/node@16.18.3
├── express@4.18.2
├── typescript@4.9.3
└── winston@3.8.2

依存パッケージがアップデートされたようです。

npm outdatedも確認してみましょう。表示されるのが@types/nodeのみになりました。

$ npm outdated
Package      Current   Wanted   Latest  Location                  Depended by
@types/node  16.18.3  16.18.3  18.11.9  node_modules/@types/node  npm-dependencies

これは、以下の記述なのでv16の範囲でしか更新されないからですね。

    "@types/node": "^16.18.0",

メジャーバージョンが変わるような場合はリリースノート等それなりに確認することもあると思うので、semverの範囲を守るのは妥当な
感じがしますね。

semverの範囲よりもさらに更新したい場合は、npm installで個々のパッケージを指定してインストールすることになります。

それでも最新版に一括でアップデートしたい、という場合はこちらを使うのではないかと思います。

npm-check-updates - npm

ところで、npm updateを実行してもpackage.jsonが変わるわけではありません。

  "dependencies": {
    "express": "^4.17.0",
    "winston": "^3.8.0"
  },
  "devDependencies": {
    "@types/node": "^16.18.0",
    "typescript": "^4.8.2"
  }

package.jsonも含めて更新する場合は、--saveオプションを付与します。

$ npm update --save

こうすると、package.jsonの記述も更新されるようになります。

  "dependencies": {
    "express": "^4.18.2",
    "winston": "^3.8.2"
  },
  "devDependencies": {
    "@types/node": "^16.18.3",
    "typescript": "^4.9.3"
  }

こんなところでしょうか。

まとめ

npmプロジェクトの依存関係を確認したり、新しいバージョンの確認、更新を行うnpmコマンドを確認してみました。

今まであんまり知りませんでしたが、けっこういろいろできるんですね。覚えておきましょう。