脱「npm installが何してるか知らないけど書いてあるからやる」

「`$ npm install`が何してるかいまいち理解していないけれどもとりあえず書いてあったからやる」の状態を脱するために色々調べた記録。

この2つ見ておけば大体のことは解る。

https://www.webprofessional.jp/beginners-guide-node-package-manager/
https://qiita.com/righteous/items/e5448cb2e7e11ab7d477

# パッケージとは？

Node.jsのプロジェクト1つはパッケージ1つと対応する。
`package.json`ファイルを含むファイル群をパッケージと称し、`package.json`ファイルがある階層がrootディレクトリとなる。

# package.json
ローカルインストールする際に自動生成されるファイル。依存関係にあるパッケージがずらっと書かれる場所。

```json:package.json
{
  "name": "app",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^0.19.2",
     :
    "vuex": "^3.1.2"
  },
  "devDependencies": {
    "@types/chai": "^4.2.5",
     :
    "vue-template-compiler": "^2.6.10"
  }
}
```

### private

`"private": true`とすることで、プライベートリポジトリを意図せずに公開する誤りを防ぐことができる。

### main

そのパッケージを外からインポートする際(require)に入り口となるjsファイルを指定する。

### script

コマンドのエイリアス。`npm run コマンド名`として実行できるようになる。
ただし、以下は予約語。

|||
|:---:|:---|
|start|プログラムを実行するコマンド。`npm start`のみで可|
|test|テストを実行するコマンド。`npm test`のみで可|
|接頭辞pre|接頭辞を除いたコマンドが打たれた際、その直前に実行してくれる。|
|接頭辞post|接頭辞を除いたコマンドが打たれた際、その直後に実行してくれる。|

### dependencies、devDependencies

パッケージが依存する別のパッケージ。`dependencies`は実行時に必須のパッケージを書き、`devDependencies`には、開発環境でのみ必要なパッケージ（テストツールなど）を記述する。

## バージョンの指定

バージョン番号`1.2.3`はそれぞれ先頭から順にMajor、Minor、Patchと呼ばれている。

|記号|意味|
|:---:|:---:|
|`^`|Majorは一致。MinorとPatchは指定されたもの以上|
|`~`|MajorとMinorは一致。Patchは指定されたもの以上|

`package-lock.json`はパッケージのバージョンを固定する目的で使用されている。
これにより、複数のdeveloperが環境構築をする際に、依存関係のモジュールのversionが合わないといったケースを避けることができる。 

* `package-lock.json`がない場合  
→ `npm install`が実行されると条件を満たす最新のパッケージがインストールされる。
* `package-lock.json`がある場合  
→ 基本`package-lock.json`に基づいてインストールされるが、`package.json`と矛盾した場合、`package.json`が優先され、実際にインストールされたバージョンが`package-lock.json`に書かれる。

# node_modules

`node_modules`ファイルは、`package.json`を元にしてインストールされる各種外部パッケージの置き場であり、これは各開発者のローカルにのみある。（通常gitignoreする。）

はじめにプロジェクトの環境を作るには`npm install`コマンドを実行し、必要なパッケージを`node_modules`へ取得する。（ローカルインストール）

```
$ npm install              //dependenciesとdevDependenciesのパッケージをインストールする。（開発環境）
$ npm install --production //dependenciesのパッケージをインストールする。（本番環境）
```

プロジェクトに新たにパッケージを追加する場合には`npm install パッケージ名`とする。

```
$ npm install パッケージ名 // 自分のローカル環境にのみインストールされる。
$ npm install --save-dev パッケージ名 //package.jsonのdevDependenciesに追記される(開発環境）
$ npm install --save パッケージ名 //package.jsonのdependenciesに追記される。（本番環境）
```

# npmインストール

グローバルインストールとローカルインストールの2種類がある。

## グローバルインストール

グローバルインストールは`{prefix}/lib/node_modules/`にパッケージをインストールする。（{prefix}は通常/usr/か/usr/local）

```
$ npm install --global "パッケージ名@バージョン"
```
（おそらくsudo必要）
なお、バージョン番号の指定はオプション。

## ローカルインストール

カレントディレクトリの`node_modules`フォルダにインストールする。

```
npm init
npm install "パッケージ名@バージョン"
```
これにより、`package.json`と`package-lock.json`が自動生成する。
アップデートorアンインストールしたい場合は以下。

```
$ npm update
$ npm uninstall
```

# その他npmコマンド

### npm outdated

```
$ npm outdated
Package     Current  Wanted  Latest  Location
underscore    1.8.2   1.8.3   1.8.3  project
```

|||
|:---:|:---:|
|Current|現在のバージョン|
|Wanted|修正なく動作可能な最新のバージョン|
|Location|最新のバージョン|

### npm list
パッケージの一覧表示。`-g`とすることでglobalの一覧表示。

```
$ npm list
```

### エイリアス一覧

|エイリアス|元のコマンド|
|:---|:---|
|$ npm i|$ npm install|
|$ npm un|$ npm uninstall|
|$ npm up|$ npm update|
|$ npm t|$ nom test|
|$ npm -v|$ npm --version|
|$ npm install -g|$ nom install --global|

# キャッシュ

npmはパッケージをインストールするときにコピーを保持し、同じパッケージが必要になったとき、ネットワークへのアクセスなく、ホームディレクトリの.npmディレクトリのコピーがキャッシュされる。

```
## 確認
$ ls ~/.npm

## クリア
$ npm cache clean
```

# 多分こんなイメージ(?)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/d2720846-facb-3a77-7578-35f8d6501253.png)