いまさら聞けないnpm dependencies – 空の箱

最近pnpmのドキュメントを眺めていたんだけど、そこでよく知らない依存関係の種類が出てきた。いまさら人に聞くのは恥ずかしいと思ったので、理解したことをまとめてアウトプットしておく。

  • そもそも依存関係とは?
  • package-lock.jsonとは?

といった話は理解できている前提で書く。

最も基本となる依存関係。npm installするとdependenciesに書かれたものは全てインストールされることになる。

なので、本番環境で使うものしかここには入れてはいけない。「ではそれ以外のものはどこにいれるのか?」となるが、基本的にはdevDependenciesとなる。

この話自体はいろんな記事やカンファレンスのトークで擦られ続けているので、もうお腹いっぱい感がある。

一応書くと、devDependenciesにインストールするにはnpm install --save-dev とする。逆に本番環境でdependenciesのみをインストールするには、npm install --omit=devと書く。

ここまではまあ基本で、以降がよく知らなかったものたち。

名前的に入れても入れなくてもどっちでもいいライブラリっぽいが本当に合ってるか裏を取る。

ドキュメントを読むと、

If a dependency can be used, but you would like npm to proceed if it cannot be found or fails to install, then you may put it in the optionalDependencies object.

ある依存関係が使用できるが、それが見つからなかったりインストールに失敗した場合にnpmに処理を進めさせたい場合は、optionalDependenciesオブジェクトにその依存関係を記述することができる。

ということらしい。裏を返すとoptionalDependenciesを含むライブラリを配布する場合はそれが失敗したとしても動く状態にしてあげないといけないことになる。

例えばNext.jsのpackage.jsonを見ると、

  "optionalDependencies": {
    "sharp": "0.26.3"
  },

となっている。sharpは画像変換のライブラリ。

www.npmjs.com

これがNext.jsのどの辺で使われているのを見てみると、image-optimizer.tsらしい。

つまり「Next.jsは使いたいけど画像は別に扱わない*1からとりあえずインストール続けてくれ」みたいなシーンではsharpがなくても問題ないため、optionalDependenciesに含まれていると思われる。

なんとなくこのライブラリを使うなら、○○がすでにインストールされている前提だよ!ってことを連想させられる名前。

ドキュメントを読むと、

In some cases, you want to express the compatibility of your package with a host tool or library, while not necessarily doing a require of this host. This is usually referred to as a plugin.

場合によっては、自分のパッケージが特定のホストツールやライブラリと互換性があることを示したいが、そのホストを直接 require する必要はないこともある。こうしたケースは、一般的に「プラグイン」と呼ばれる

ということらしい。要はpeerDependenciesに書かれたライブラリは、必ずしもpeerDependenciesを要求する側でinstallする必要がないということらしい。これは実例をいくつか見るのがよさそう。

例えばoptionalDependenciesに続いてNext.jsのそれを見てみる。

  "peerDependencies": {
    "fibers": ">= 3.1.0",
    "node-sass": "^4.0.0 || ^5.0.0",
    "react": "^16.6.0 || ^17",
    "react-dom": "^16.6.0 || ^17",
    "sass": "^1.3.0"
  },

わかりやすいのはReactで、確かにNext.jsはそもそもReactがないと動かない。けどNext.jsにReactが同梱されているわけではなくて、公式ドキュメントの手順にもあるとおりReactは個別にインストールすることになる*2

あとは引用したnpmのドキュメントの通り、プラグインをみるといいのかも。ってことでeslintのpluginであるeslint-plugin-unicornのpackage.jsonをみると以下のようになっている。

   "peerDependencies": {
        "eslint": ">=9.22.0"
    },

eslint-plugin-unicornについては過去に記事を書いている。

zenn.dev

依存関係をまとめてなんかするっぽいけど、具体的になにをするんだろう。名前から一番イメージ湧かないのがこれ。

ドキュメントによると、

This defines an array of package names that will be bundled when publishing the package.
In cases where you need to preserve npm packages locally or have them available through a single file download, you can bundle the packages in a tarball file by specifying the package names in the bundleDependencies array and executing npm pack.

これは、パッケージの公開時にバンドルされるパッケージ名の配列を定義します。
npm パッケージをローカルに保存したり、単一のファイルのダウンロードで利用できるようにしたりする必要がある場合は、 bundleDependencies 配列にパッケージ名を指定して npm pack を実行することで、パッケージを tarball ファイルにバンドルできます。

ということらしい。つまり、bundleDependenciesに指定したものはパッケージを公開するタイミングでこのライブラリのnode_modulesに含まれることになる。なので、

  • 外部に公開されていない、あるいはしていない(例えば内部用に作った)パッケージを含めたい時
  • もともとnpmリポジトリにあったけど今は配布されてなくて、自分の手元にしかなくなっちゃったライブラリ*3

みたいなシーンで使うことになりそうだと思った。


Source link

関連記事

コメント

この記事へのコメントはありません。