Javascript(Node.js)プロジェクトの開発者は必須！　ncuコマンドでパッケージを最新化する

## はじめに
Javascript(Node.js)のプロジェクトで、最初にインストールした時のままのバージョンでずっと開発をしていた、なんて事にならないように定期的にバージョンを更新していく必要があると思う（バージョン更新を後でまとめてやろうとしても変わりすぎて動かない…、なんて事もあるので1週間に1回とかできるだけ高頻度で更新するのが後々楽）。
今回は実際に勉強で作成していたプロジェクトのバージョンを更新してみたので、その備忘録を残す。

## 実際にパッケージの更新をやってみる
[npm-check-updates](https://github.com/raineorshine/npm-check-updates)を利用する。

```console
[root@localhost node-express]# yarn global add npm-check-updates
yarn global v1.22.17
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "npm-check-updates@12.5.9" with binaries:
      - npm-check-updates
      - ncu
Done in 10.86s.
```

あとは以下のように`ncu`コマンドを実行すれば、パッケージの更新があったものを一覧で提示してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/7f1c4c5e-59e8-8124-3a91-687388b63762.png)

更新を行う（package.jsonを書き換える）場合には、`ncu- u`コマンドを実行すればいい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/b8505cc2-958f-c2c6-cd1a-6b2b4e8421a5.png)

続いてpackage.jsonが書き換わった後は`yarn install`でyarn.lock・node_modulesの更新を行えば更新作業は完了(`yarn upgrade`は`yarn install`時にpackage.jsonの更新内容に基づいて最新のバージョンに更新されるので不要の認識 ← だったが、どうやらそうではなく、`yarn upgrade`も必要（yarn install後にyarn upgradeをしたらyarn.lockが書き換わったケースがあったので）。詳細は[yarn upgrade(npm update)との違い](#yarn-upgradenpm-updateとの違い)を参照。）。

自分自身のプロジェクトでやってみた結果としては、以下のようになった。

https://github.com/yuta-katayama-23/node-express/commit/a9c374281aa533da3ee4820f73d0bd23456b6414

※今回はグローバルインストールを行ったが、現在開発しているプロジェクトでのみ利用する際には、`yarn add --dev npm-check-updates`でpackage.jsonに追加した後、`npx ncu`を実行すればグローバルにインストールしなくてもnpm-check-updatesを利用できる。

※yarnではなくnpmを利用している方は、[npmとyarnのコマンド早見表](https://qiita.com/rubytomato@github/items/1696530bb9fd59aa28d8)等を参照する事でnpmに読み替えできると思う。

## パッケージのバージョンを更新したくない時には…
公式の[Configuration Files](https://github.com/raineorshine/npm-check-updates#configuration-files)に書かれている
configファイル`.ncurc.json`を作成し、その`reject`の配列にパッケージ名を記載すればいい。

```json
{
	"reject": ["vue"]
}
```

上記のように設定すると、以下の画像の通り、設定前のncuコマンドの実行結果にはvueのバージョン更新に関してリストが出力されているが、設定後には表示されなくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1372684/19302a3f-a3ff-c877-4c58-96f093b38d76.png)

この設定はプロジェクトごとの事情によりパッケージのバージョンを固定化する時などに便利。ちなみに、上記はVue2.x系とVue3.x系では全く別物なのでVueのパッケージを更新しないようにする設定。

## yarn upgrade(npm update)との違い
今回上記でやった事に関して、`yarn upgrade`との違いについて、少し触れておく。

まず、前提として、package.jsonとlockファイル（yarn.lockやpaclage-lock.json）との関係性についてだが、package.jsonは依存関係のあるライブラリ（パッケージ）を管理するためにあるが、全ての依存関係のあるパッケージのバージョン指定まではできない。一方、lockファイル（yarn.lock）は依存関係のある全てのライブラリ（自身が利用しているライブラリの中で依存しているライブラリまで）の依存関係を固定化するためにある（この辺りの詳細については、以下の参考に示した記事を参照）。

本題のyarn upgradeについてだが、[yarn upgrade](https://classic.yarnpkg.com/en/docs/cli/upgrade)に以下のように書かれている通り、package.jsonの指定バージョン範囲で最も最新のバージョンでyarn.lockを更新するためのコマンド。つまり、package.json自体に定義されているバージョンを最新化するのではなく、既存のpackage.jsonのバージョン指定範囲で最新のバージョンにするという事をする。

> This command updates dependencies to their latest version based on the version range specified in the package.json file. The yarn.lock file will be recreated as well.（package.json ファイルに指定されたバージョン範囲に基づいて、依存関係を最新バージョンに更新します。yarn.lock ファイルも同様に再作成されます。）

そのためpackage.jsonで指定しているバージョン範囲を最新にしたい場合には、yarn upgradeではダメで他のコマンドを実行する必要がある。そこで利用したのが[npm-check-updates](https://github.com/raineorshine/npm-check-updates)。

※package.jsonやyarn.lockで出てくる`~`や`^`については[dependencies](https://docs.npmjs.com/cli/v8/configuring-npm/package-json#dependencies)に詳細が書かれている。

※`yarn install`では何をするのか？だが、それは[yarn install](https://classic.yarnpkg.com/en/docs/cli/install#toc-yarn-install)に書かれている通り、基本的にはyarn.lockに書かれているバージョンで各ライブラリをインストールしnode_modules以下を作成するが、もしpackage.jsonとのずれがあればpackage.jsonのバージョン指定範囲を満たすように最新のバージョンを探し出し、それに基づき各ライブラリをインストールする、という事をする。

> The yarn.lock file is utilized as follows:（yarn.lockファイルは、以下のように利用されます。）
>
>・If yarn.lock is present and is enough to satisfy all the dependencies listed in package.json, the exact versions recorded in yarn.lock are installed, and yarn.lock will be unchanged. Yarn will not check for newer versions.（yarn.lockが存在し、package.jsonに記載されているすべての依存関係を満たすのに十分であれば、yarn.lockに記録されている正確なバージョンがインストールされ、yarn.lockは変更されません。Yarnはより新しいバージョンをチェックしません。）
>
>・If yarn.lock is absent, or is not enough to satisfy all the dependencies listed in package.json (for example, if you manually add a dependency to package.json), Yarn looks for the newest versions available that satisfy the constraints in package.json. The results are written to yarn.lock.（yarn.lockがない場合、またはpackage.jsonに記載されているすべての依存関係を満たすのに十分でない場合（例えば、手動でpackage.jsonに依存関係を追加した場合）、Yarnはpackage.jsonの制約を満たす利用できる最新のバージョンを探します。その結果はyarn.lockに書き込まれます。）

- 参考：[【npm,yarn】今さら聞けないlockファイル](https://zenn.dev/nekoniki/articles/ec5bb4d16ef20a)
- [package-lock.json](https://qiita.com/righteous/items/e5448cb2e7e11ab7d477#package-lockjson)