npmってなんなのさ

## はじめに
Node.jsを使って開発をしていると避けて通れないのが`npm`コマンドです。
この`npm`が何であるかを調べると
「Node Package Manage」の略で、Node.jsのパッケージの管理をする
という説明が多く見られます。
しかし、私にはこれではピンとこないので、自分なりに調べた結果をまとめます。

## npmとは
以下の公式サイトを確認します。
[About npm | npm Docs](https://docs.npmjs.com/about-npm)

npmとひとくちに言っても、その実態は大きく3つのことを指すようです。
* Webサイトとしてのnpm
* CLIとしてのnpm
* レジストリとしてのnpm

よく目にするのは「CLIとしてのnpm」です。要はコマンドとして使うnpmです。
しかし、この3つの中でも個人的に重要なのは「レジストリとしてのnpm」だと考えます。
公式ドキュメントのはじめの文章にはnpmが世界最大級のレジストリであると書かれています。

つまり、npmの本質は巨大なJavaScriptのデータベースであると言えそうです。
そのデータベースに「Webサイトとしてのnpm」を通して世界中の人がJavaScriptのパッケージを公開し、そのパッケージが「CLIとしてのnpm」によって利用可能となる、ということのようです。

## CLIとしてのnpm
npmの本質に触れられたので割ともう満足なのですが、「Node.jsのパッケージを管理する」という部分についての理解が及んでいないので、「CLIとしてのnpm」についてもう少し詳しく見てみます。

### そもそもパッケージとは
パッケージについての説明は数多くあり、私も正確な理解ができているとは言い難いですが（パッケージ、ライブラリ、モジュールなど似た用語が多数ある）、大雑把にJavaScriptの便利ファイルをまとめたものとして捉えてよいでしょう。

JavaScriptはファイルのインポート、エクスポートができます。
これにより、作成した関数などを他のファイルでも利用することができます。

DBとの接続や、ファイルの読み書きなどの煩雑な処理を、何度も実装せずとも便利に使えるようあらかじめ用意し、ひとまとまりにまとめたものがパッケージと言えます。

### なぜnpmなのか
npmを使う最大の理由は、もちろん便利だからです。
それは公開されている便利なパッケージをコマンドでサクッとインストールできるから、だけではありません。
dependency（依存関係）を解決してくれるのが最大の利点です。

先に上げたように、便利機能の集まりがパッケージです。
そのパッケージを作る際、パッケージ内で別のパッケージを利用することもできます。

例えば、ファイルの読み書きを便利にするAというパッケージを作る際、ファイルの出力時にファイルの中身をフォーマットできるよう、Bというパッケージを使うようにしたとします。

そうなると、Aのパッケージを動かすためには、Bのパッケージも必要なことになります。

Aを利用しようとしているひとは、中身の実装までは当然知りませんから、Bが必要なことはわかりません。

このとき、npmを使えば、Aのインストール時にAを動かすのに必要なBも自動でインストールしてくれるのです。

試してみましょう

適当な空のディレクトリを作成し、そのディレクトリで以下のコマンドを実行します。
※Node.jsを導入している前提です。
```bash
npm init
```
以下のように色々聞かれますが、すべて`enter`でよいです。
<img width='70%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/46435b03-c085-f2a0-186d-119340e5a272.png'>

そうすると、以下のように`package.json`ファイルが生成されます。
ここに、npmでインストールしたファイルが記録されていきます。

:::note warn
package.jsonファイルは本来様々な設定を書けるファイルですが、今回は一旦インストールしたものが書かれるものとして扱います。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/125d810f-fc62-cd56-2f83-7ed07d3f594e.png)

ここで、一つ試しに適当なパッケージをインストールしてみます。
```bash
npm install express
```
expressはWebアプリケーションを作るための便利なパッケージです。

以下はインストール後の`package.json`の中身と、フォルダの中身です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/e06f8ee6-9711-dfdb-9153-bdd6b07d5cbc.png)

`package.json`には`dependencies`という項目が追加されており、そこにexpressが追加されています。

また、ファイルとして`package-lock.json`、フォルダとして`node_modules`が追加されています。
`package-lock.json`は今回は置いておきます。
`node_modules`にはインストールしたパッケージが追加されます。

では、中身を見てみます。
<img width='40%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/e60aaa71-5341-765d-7a74-654069367e85.png'>
express以外に数多くのフォルダが作成されているのがわかります。
これが、冒頭でふれた依存関係です。

今回インストールするものとして指定したのはexpressのみですが、expressを動かすために必要な他のパッケージも自動でインストールしてくれています。

では、それはどこで判定しているのでしょうか。

expressフォルダ内に`package.json`という別のフォルダがあるので、中身を見てみます。

<img width='70%' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/6b1eb4e5-9fbb-b2fe-2fc0-b25610533353.png'>

`dependencies`にずらっと色々なパッケージ名が列記されています。
よくみると、すべてではありませんが、ここに書き連ねられているパッケージと、`node_modueles`にあるexpress以外のフォルダ名が一致しています。

この`dependencies`とは「ここに書いているパッケージに依存していますよ」ということを指し示す設定になっています。
expressというパッケージは`dependencies`に書いているパッケージを使っているので、これらも必要ですよ、ということをnpmに伝えています。

よって、expressをインストールするだけで、その他必要なパッケージも一緒にインストールしてくれるのです。


## まとめ
普段何気なく書いているコマンドも、そのバックグラウンドを知ると、なんのためのコマンドなのかという理解が深まります。

やはり、難解ではありますが、公式ドキュメントに繰り返し目を通すことが大事なのだということがわかりました。

わかったふうに書いていますが、まだまだ調べる中でわからないこと、気になることはたくさん出てきたので、今後また折に触れて記事にしていきたいと思います。