mizdra's blog

ぽよぐらみんぐ

ある npm package がどこから依存されているか調べる方法

このパッケージってどこからどう依存されてるんだっけ、と調べる時によく打ってるのでメモ。

npm

npm v7 以降であれば npm explain <package> というサブコマンドでできる。npm v7 以前は npm-whynls を別途インストールしてきて、それを使う必要があった。ちなみに npm why という名前の npm explain の alias も用意されている。

$ npm explain ts-node
ts-node@10.9.1 dev
node_modules/ts-node
  dev ts-node@"^10.9.1" from the root project
  peerOptional ts-node@">=9.0.0" from jest-config@28.1.3
  node_modules/jest-config
    jest-config@"^28.1.3" from @jest/core@28.1.3
    node_modules/@jest/core
      @jest/core@"^28.1.3" from jest@28.1.3
      node_modules/jest
        dev jest@"28.1.3" from the root project
        peer jest@"^28.0.0" from ts-jest@28.0.8
        node_modules/ts-jest
          dev ts-jest@"28.0.8" from the root project
      @jest/core@"^28.1.3" from jest-cli@28.1.3
      node_modules/jest-cli
        jest-cli@"^28.1.3" from jest@28.1.3
        node_modules/jest
          dev jest@"28.1.3" from the root project
          peer jest@"^28.0.0" from ts-jest@28.0.8
          node_modules/ts-jest
            dev ts-jest@"28.0.8" from the root project
    jest-config@"^28.1.3" from jest-cli@28.1.3
    node_modules/jest-cli
      jest-cli@"^28.1.3" from jest@28.1.3
      node_modules/jest
        dev jest@"28.1.3" from the root project
        peer jest@"^28.0.0" from ts-jest@28.0.8
        node_modules/ts-jest
          dev ts-jest@"28.0.8" from the root project

実際にインストールされているバージョンに加えて、@^a.b.c みたいに、どういうバージョン制約で依存されているのかまで出るのが便利 (この制約のせいで major バージョンアップができない…みたいなのがひと目で分かる)。

yarn

yarn why <package> でできる。こちらは昔からある。

$ yarn why minimist
yarn why v1.22.19
[1/4] 🤔  Why do we have the module "minimist"...?
[2/4] 🚚  Initialising dependency graph...
[3/4] 🔍  Finding dependency...
[4/4] 🚡  Calculating file sizes...
=> Found "minimist@1.2.5"
info Has been hoisted to "minimist"
info Reasons this module exists
   - Hoisted from "json5#minimist"
   - Hoisted from "netlify-lambda#babel-loader#mkdirp#minimist"
   - Hoisted from "netlify-lambda#webpack#mkdirp#minimist"
   - Hoisted from "webpack-dev-server#portfinder#mkdirp#minimist"
   - Hoisted from "workbox-webpack-plugin#workbox-build#@surma#rollup-plugin-off-main-thread#json5#minimist"
info Disk size without dependencies: "104KB"
info Disk size with unique dependencies: "104KB"
info Disk size with transitive dependencies: "104KB"
info Number of shared dependencies: 0
=> Found "mkdirp#minimist@0.0.8"
info This module exists because "mkdirp" depends on it.
info Disk size without dependencies: "72KB"
info Disk size with unique dependencies: "72KB"
info Disk size with transitive dependencies: "72KB"
info Number of shared dependencies: 0
=> Found "tsconfig-paths#minimist@1.2.0"
info Reasons this module exists
   - "eslint-plugin-import#tsconfig-paths" depends on it
   - Hoisted from "eslint-plugin-import#tsconfig-paths#json5#minimist"
info Disk size without dependencies: "96KB"
info Disk size with unique dependencies: "96KB"
info Disk size with transitive dependencies: "96KB"
info Number of shared dependencies: 0
=> Found "netlify-lambda#json5#minimist@1.2.0"
info This module exists because "netlify-lambda#webpack#loader-utils#json5" depends on it.
info Disk size without dependencies: "96KB"
info Disk size with unique dependencies: "96KB"
info Disk size with transitive dependencies: "96KB"
info Number of shared dependencies: 0
=> Found "babel-loader#json5#minimist@1.2.0"
info This module exists because "netlify-lambda#babel-loader#loader-utils#json5" depends on it.
✨  Done in 0.23s.

yarn whynpm why と違って、どういうバージョン制約で依存されているのかまでは出ない。バージョン制約を調べたければ、cat node_modules/tsconfig-paths/package.json | jq .dependencies.minimist とかやって頑張るしかないはず (もっと良い方法あれば教えて下さい)。

$ cat node_modules/tsconfig-paths/package.json | jq .dependencies.minimist
"^1.2.0"

pnpm

pnpm why <package> でできる。

$ pnpm why postcss
Legend: production dependency, optional only, dev only

happy-css-modules@0.4.0 /Users/mizdra/src/github.com/mizdra/happy-css-modules

dependencies:
postcss 8.4.17
postcss-modules 4.3.1
├── postcss 8.4.17 peer
├─┬ postcss-modules-extract-imports 3.0.0
│ └── postcss 8.4.17 peer
├─┬ postcss-modules-local-by-default 4.0.0
│ ├─┬ icss-utils 5.1.0
│ │ └── postcss 8.4.17 peer
│ └── postcss 8.4.17 peer
├─┬ postcss-modules-scope 3.0.0
│ └── postcss 8.4.17 peer
└─┬ postcss-modules-values 4.0.0
  ├─┬ icss-utils 5.1.0
  │ └── postcss 8.4.17 peer
  └── postcss 8.4.17 peer

だいたい yarn why と同じだけどこちらのほうがスッキリしてる。あと依存の種類 (dependencies なのか devDependencies なのか peerDependencies なのか) が出ているのが特徴。

ちなみに pnpm why -D <package>devDependencies に絞ったりもできる。

まとめ

  • <npm|yarn|pnpm> why と打てば良い
  • npm why はどういうバージョン制約で依存されているのかまで出て便利

ポケットモンスター・ポケモン・Pokémon・は任天堂・クリーチャーズ・ゲームフリークの登録商標です.

当ブログは @mizdra 個人により運営されており, 株式会社ポケモン及びその関連会社とは一切関係ありません.