Nodeのパッケージ管理を管理したい話

## はじめに
Nodeのパッケージ管理ツールって複雑なのです。いわゆる”yarn”や”npm”とか。聞いたこと、実行したことあるのではないのでしょうか。
結局どっちで管理してるの？すべきなの？いやいや他にもパッケージ管理ツールってあるんだよ。というお話をします。


## パッケージ管理ツール
そもそもパッケージ管理ツール、ってなんなのよ。このパッケージ管理ってなんで必要なのという話からです。


ソフトウェア開発では複数のパッケージが必要になります。

例えばこんなコードを書きたいとします。ReactのHooksらを用いてルーティングし、MUIでコンポーネントを構成します。
すると書きたいコードの上にこのようなimport文を書きます

```typescript
import { Box, Typography } from "@mui/material";
import { useEffect, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
```

これは利用したいパッケージをインストールしており、そこから利用したい関数を引っ張ってきている、ということです。

ここでの外部から開発で利用したいパッケージの管理をする、のがパッケージ管理ツールの役割の1つです。また大きな開発になればなるほどたくさんのパッケージを利用します。それらの管理やパッケージのバージョンも合わせて管理してくれます。

また、あるパッケージを実行するためには別のパッケージが必要、というようなパッケージの依存関係がある場合もあります。その場合もパッケージ管理ツールがそのような依存関係の解決をしてくれたりします。

```bash
yarn install
```

とあるプロジェクトで必要なパッケージをインストールするなら、上記で一発です。やー簡単簡単。
例としてyarnを利用しましたが、色々なパッケージ管理ツールがあります。それぞれについて軽くご紹介していきます。

## npm

まずは”npm”。2010年にnpm社がリリースしており、nodeにデフォルトで入っているため個別インストール不要なパッケージ管理ツールです。package-lock.jsonファイルを用いて、パッケージ管理を行います。


npmコマンドを一例として記載します。
```bash
# パッケージのインストール
npm install {パッケージ名}
# パッケージの更新
npm update　{パッケージ名}
# スクリプトの実行
npm run dev
```

参照：[npm公式サイト](https://www.npmjs.com/)

:::note info
記載している、2024/7/25 現在
Latest（最新バージョン）: v10.8.2
です。ご注意ください
:::
## yarn

（自身のPJTでこちらを利用しており、個々の種類でつまずきました）
一言、このPJTではパッケージ管理ツールはyarnを利用しています、といってもyarn Classicとyarn Modernと大きく違います。

### yarn Classic（v1）

yarnの最初のバージョンで、npmに対する主な改善点として、より高速なパッケージのインストールと、ネットワーク接続の信頼性の向上が挙げられます。また、yarn.lockファイルを使用して、パッケージ管理を行います。

:::note info
記載している、2024/7/25 現在
Classic Stable（安定バージョン）: v1.22.22
です。ご注意ください
:::

参照：[yarn Classic公式サイト](https://classic.yarnpkg.com/lang/en/)

### yarn berry（v2）

node_modulesを利用せず、代わりに依存関係のマッピング用ファイル、pnp.cjsを用いることによって、パフォーマンス向上したバージョンとなります。このPnPはパッケージごとにzipに再圧縮して.yarn/cache内に保存します。この.yarn/cacheをgitにコミットしてしまうというワークフローをZero-Installsと呼び、yarn v2は通常のPnPとZero-Installsの両方を利用可能です。

### yarn Modern（v3/v4）

yarnの最新バージョンを指します。yarn Classicよりも新しい機能（yarn dlx、builtin patch: protocolなど）が追加あったり、yarn berry同様、PnPおよびZero-Installsを利用可能です。

yarnコマンドを一例として記載します。
```bash
# パッケージのインストール
yarn add {パッケージ名}
# パッケージの更新
yarn upgrade {パッケージ名}
# スクリプトの実行
yarn dev
```
参照：[yarn Modern公式サイト](https://yarnpkg.com/)

:::note info
記載している、2024/7/25 現在
Latest（最新バージョン）: v4.3.1
です。ご注意ください
:::

## pnpm

前者説明のnpm、yarnよりもパフォーマンスに特化したパッケージ管理ツールです。pnpmでインストールされたパッケージの実態ファイルはグローバルに管理されるため、異なるプロジェクト間でも共有可能になります。そのためディスク容量を節約と、インストールの高速化が実現できます。
また、pnpm-lock.yamlファイルを利用して、パッケージ管理を行います。

pnpmコマンドを一例として記載します。
```bash
# パッケージのインストール
pnpm add {パッケージ名}
# パッケージの更新
pnpm upgrade {パッケージ名}
# スクリプトの実行
pnpm dev
```

参照：[pnpm公式サイト](https://pnpm.io/ja/)

:::note info
記載している、2024/7/25 現在
Latest（最新バージョン）: v9.6.0
です。ご注意ください
:::

## パフォーマンス比較

ここで管理ツールを選択する際の1つの指標となる実行速度です。毎日更新されているため、ぜひこちらご確認ください！

参照：[Benchmarks of JavaScript Package Managers](https://pnpm.io/ja/benchmarks)


## corepack

上記解説らパッケージ管理ツールを管理するツールがcoreoackです。Node.js 16.10 より後のバージョンにはデフォルトで含まれています。
異なるバージョンのパッケージ管理ツールを簡単に切り替えることができます。これにより、プロジェクトごとに適切なパッケージ管理ツールを使用することが可能になります。

それも切り替えも簡単。もし、yarnを利用したい、と思ったなら以下のコマンドで有効化します。

```bash
corepack enable yarn
```
バージョンについては、package.json に packageManager として記載します。
例えば以下のように、パッケージ名＋バージョンを記載します。
```json
{
  "packageManager": "yarn@3.2.0"
}
```

参考：[corepack is 何?](https://zenn.dev/teppeis/articles/2021-05-corepack)

:::note warn
追記
corepackがNode.jsから削除になったため非推奨となります。
参照詳細はこちら
[RIP 2024年こそ corepack を使おうとしたら終わった](https://zenn.dev/monicle/articles/b7a9314f9f1efb)
:::


## まとめ
今回たくさんあるパッケージ管理ツールについて、調査と比較を行っていきました。どれを選択するか、というのは個人の選択に依存しますが、一度自分が利用しているツールについて確認してみるのはいかがでしょうか。また、調べてみると、パッケージ管理ツールの移行（yarnからnpmへ）も多く記事が出てきました。より最適なツールの見直し、もよきですね。
引き続き日々の学びの視野と意識を保って継続発信していければと思います。よろしくお願いします〜！



### 参考資料
[node_modulesの問題点とその歴史](https://zenn.dev/saggggo/articles/dbd739508ac212)
[yarnのよくある質問](https://yarnpkg.com/getting-started/qa#why-should-you-upgrade-to-yarn-modern)