npmとyarnの細かい挙動の違いまとめ

# 環境
|  |バージョン  |
|---|---|
|npm  |6.14.4|
|yarn  |1.22.4

# npm
## npm install
エイリアス: `npm i`、`npm add`

### 引数なし
`npm install`の引数に何も与えなかった場合、package.jsonの内容から、依存パッケージをインストールします。この時、package-lock.jsonとnode_moduleディレクトリの内容で若干挙動が変わります。
例えば、次のようなpackage.jsonのみがある時、`npm install`するとpackage-lock.jsonとnode_moduleディレクトリが作成され、jqueryのバージョン2.4.4がインストールされます。バージョンの指定方法については[こちら](https://qiita.com/chihiro/items/5826678bc9287fb57a28)の記事がわかりやすかったです。

```package.json
...
 "dependencies": {
    "jquery": "^2.2.0"
  }
...
```

```
-> % npm install
...
-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.4",   # 2.2.4がインストールされる
...
```

しかし、既に"^2.2.0"を満たすようなバージョンがインストールされていると、パッケージの更新は起こりません。インストール済みのパッケージが新しいバージョンをリリースした時などに起こります。

```
-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.0"   # 既に2.2.0がインストール済み
...

-> % npm install

-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.0"   # 変化なし
..

```


### 引数あり

`npm install <package name>`とすることでパッケージの追加ができます。また、`<package name@version>`とすることでバージョンの指定もできます。バージョンを指定した場合、package.jsonには`^`がついた状態で追加されます。

```
-> % npm install async@3.0.0
...
-> % cat package.json
...
  "dependencies": {
    "async": "^3.0.0",
    "jquery": "^2.2.0"
  }
...

-> % npm install async@^3.0.0
...
-> % cat package.json
...
  "dependencies": {
    "async": "^3.2.0",
    "jquery": "^2.2.0"
  }
...
```


`npm install <package name>`とするときに、　`<package name>`が既にインストール済みの時、package.jsonの記述にしたがってパッケージのアップデートを行ってくれます。

```
-> % npm install jquery
```

```package.json
...
  "dependencies": {
    "jquery": "^2.2.4"   # "^2.2.0" -> "^2.2.4"
  }
...
```

## npm update
エイリアス: `npm up`, `npm upgrade`

### 引数なし
`npm update`の引数に何も与えなかった場合、package.jsonのみある時は`npm install`と同じ動きをします。**package.json自体の更新等は行いません**。

```package.json
...
 "dependencies": {
    "jquery": "^2.2.0"
  }
...
```

```
-> % npm update
...

-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.4",   # 2.2.4がインストールされる
...

-> % cat package.json
...
  "dependencies": {
    "jquery": "^2.2.0"   # package.jsonの内容は変わらない
  }
...
```

`npm install`と違うのは、既に"^2.2.0"を満たすようなバージョンがインストールされいてもパッケージの更新を行ってくれるところです。


```
-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.0",   # 既に2.2.0がインストール済み
...

-> % npm install
...

-> % cat package-lock.json
...
  "dependencies": {
    "jquery": {
      "version": "2.2.4",   # 2.2.0 -> 2.2.4
...
```


### 引数あり

`npm update <package name>`とすることでそのパッケージのみ更新ができます。まだインストールされていないパッケージを指定した場合は**インストールはされずスキップされます**(エラーなども発生しません)。

```
-> % npm update jquery async
...

-> % cat package.json
...

  "dependencies": {
    "jquery": "^2.2.4"   # 2.2.0 -> 2.2.4 & asyncはインストールされない。
  }
..
```

# yarn

## yarn install
`yarn install`は`npm install`に対応するコマンドで、package.jsonから依存パッケージをインストールするときに使います。yarn.lockとnode_moduleディレクトリの内容でインストールされるバージョンが変わるのも同様です。


## yarn add
`yarn add`も`npm install`に対応するコマンドです。yarnではパッケージの追加を行うコマンドは`yarn install`と分けられています。

### 新規パッケージをインストールするとき
基本的には`npm install`と同じですが、バージョンの指定を行うとき、yarnでは`yarn add <package name@version>`の`version`に当たる部分が直接package.jsonに記述されます(npmのように`^`の形式に直されない)。

```
-> % yarn add jquery@2.2.0   # ^なし
...

-> % cat package.json
...
  "dependencies": {
    "jquery": "2.2.0"   # ^がつかない
  }
...

-> % cat yarn.lock
...
jquery@2.2.0:
  version "2.2.0"   # 2.2.0がインストールされる
...


-> % yarn add jquery@^2.2.0   # ^あり
...

-> % cat package.json
...
  "dependencies": {
    "jquery": "^2.2.0"   # ^がつく
...

-> % cat yarn.lock
...
jquery@^2.2.0:
  version "2.2.4"   # 2.2.4がインストールされる
...
```

### 既存パッケージを指定するとき
`npm install <package name>`では、`<package name>`が既にインストールされている時はpackage.jsonの内容に従いパッケージの更新が行われましたが、`yarn add <package name>`では**package.jsonの内容に関わらず最新バージョンへ更新されます**。npmと大きく挙動が違うので注意する必要があります。

```
-> % yarn add jquery@2.2.0   # 2.2.0をインストール
...

-> % cat package.json
...
  "dependencies": {
    "jquery": "2.2.0"   # package.jsonには2.2.0の指定がされる
...

-> % yarn add jquery   # jqueryを更新
...

-> % cat package.json
  "dependencies": {
    "jquery": "^3.5.0"   # 3.5.0がインストールされる！
...
```

## yarn upgrade
`yarn upgrade`は`npm update`に対応するコマンドです。`yarn add`とは違い、package.jsonに従い更新を行います。

```
-> % cat package.json
...
 "dependencies": {
    "jquery": "^2.2.0"
...

-> % cat yarn.lock
...
jquery@^2.2.0:
  version "2.2.0"   # 2.0.0がインストールされている
...

-> % yarn upgrade
...

-> % cat package.json
...
 "dependencies": {
    "jquery": "^2.2.0"  # 変化なし
...

-> % cat yarn.lock
...
jquery@^2.2.0:
  version "2.2.4"   # 2.0.4がインストールされる
...
```