こんにちは、みんな! さまざまなパッケージ マネージャーを使用している を見たことがあると思います。たとえば、 Node.js プロジェクト (デフォルトのもの) npm 糸 ピンポン 私自身もそれを見てきましたし、上記のすべてに取り組んできましたが、常に疑問がありました。人々やチームが ではなく や を使用する理由は何でしょうか? メリットは何でしょうか? デメリットはあるのでしょうか? npm yarn pnpm さて…調べてみましょう! パフォーマンス比較ルール 、 を「速度」の観点から比較してみることにしました... npm yarn、 pnpm 以下に 3 つの対策が表示されます。 キャッシュなしでロック ファイルを生成します。 キャッシュなしで既存のロック ファイルから依存関係をインストールします。 グローバル キャッシュを使用して既存のロック ファイルから依存関係をインストールします。 キャッシュには 2 つの種類があります。 グローバル。 通常、ユーザーのホームディレクトリ (fe、 ) に保存されます。 ~/.yarn/berry/cache 地元。 プロジェクト ディレクトリ (fe、 ) に保存されます。 <project-dir>/.yarn 私の経験では、 と が最も一般的な使用例ですが、念のため も採用しました (ただし、非常にまれなケースです)。 #2 #3 #1 ベンチマークの例として のサンプル プロジェクトを使用しました。 、create-react-app ネプ これは、 エコシステムのデフォルトのパッケージ マネージャーです。他に何を言うべきでしょうか。インストール パッケージに付属しているため、基本的には、マシンに インストールするとすぐに使用できます (または、 プロバイダーで をセットアップした場合は、そのプロバイダーにインストールします)。 Node.js Node.js を CI Node.js これは私にとって大きな「利点」です。別途インストールする必要はありません。 特に目立つ点はありません。ただ…動作します。また、長年大きなバグは見ていません。かなり安定しており、問題なく動作します。 これまで使用した の機能: npm 依存関係の管理(インストール、削除、更新) パッケージを公開する(プライベート、パブリック) リンクローカルパッケージ ワークスペースを管理します。 依存関係の管理 依存関係をプロジェクト ルートの フォルダーに保存します。非常に簡単です。 npm は node_modules ℹ️ リストされている のレジストリに関する情報を保存します。単一のスコープ、つまり からのパッケージを異なるレジストリ (例: と ) に持っている場合に非常に便利です。 package-lock.json パッケージ @example-company npm GitHub パッケージ さて、インストール速度の面でのパフォーマンスを見てみましょう... キャッシュなしでpackage-lock.jsonを生成する かかった を生成し、キャッシュなしで依存関係をインストールします。 1分 npm が package-lock.json 使用されたコマンド: npm i キャッシュなしでpackage-lock.jsonから依存関係をインストールする かかった キャッシュなしで から依存関係をインストールできるようにします。 18秒 npm が package-lock.json 使用されたコマンド: npm ci グローバルキャッシュを使用して package-lock.json から依存関係をインストールする かかった グローバル キャッシュを使用して から依存関係をインストールします。 8秒 npm が package-lock.json 使用されたコマンド: npm ci ワークスペースの管理 を作成し、ワークスペース全体の依存関係を一度に管理したり、特定のプロジェクトの依存関係を個別に管理したりできるようになりました。 ワークスペース 言い換えれば、バグや問題なく作業が完了し、公式ドキュメントも非常にわかりやすいということです。 これまで使用したワークスペース機能: ワークスペース内のすべてのプロジェクトの依存関係をインストールします。 特定の単一のプロジェクトの依存関係をインストールします。 すべてのプロジェクトに対して単一のスクリプトを一度に再帰的に実行します。 糸 正直に言うと、私は 機能のいくつかをあまり試していません。つまり、いくつかのプロジェクトで作業中に「依存関係のインストール」という点でそれをたくさん使用しましたが、それだけです。 yarn の には インストーラーが付属していないため、別途インストールする必要があります。つまり、 パイプラインに追加の手順が必要になります。つまり、プロジェクトの依存関係をインストールする前に を設定する必要があります。 yarn Node.js CI yarn 依存関係の管理 には依存関係をインストールする 2 つの方法があります。 yarn 「 」(デフォルト) - フォルダーを作成し、 および ファイルにパッケージをリストします。 ゼロインストール .yarn yarn.lock .pnp.cjs 通常のものは に似ており、依存関係を に保存し、 ファイルにリストします。 npm node_modules yarn.lock ℹ️ lock ファイルには、古い (通常の) インストール方法を使用する場合にのみ リストされているすべてのパッケージのレジストリに関する情報が保存されます。 yarn 、 ⚠️ 「 」はパッケージをローカル キャッシュに保存し、ロック ファイルへのリンクを提供しているようです。 Zero Installs 依存関係を 1 つのクリーンな環境にインストールし、それを別の環境に移動する または パイプラインがある場合、これは重要になる可能性があります ( フォルダーとローカル キャッシュの両方をコピーする必要があります)。 Dockerfile CI .yarn 現在、yarn のデフォルトのアプローチは「 」であり、古いアプローチよりもパフォーマンスが優れているため、このアプローチのみでベンチマークを記録します。 ゼロ インストール キャッシュなしでロックファイルを生成する かかった ファイルを生成し、キャッシュなしで依存関係をインストールします。 16.5秒 yarn が yarn.lock 使用されたコマンド: yarn install キャッシュなしで既存のロックファイルから依存関係をインストールする かかった 「ゼロ インストール」アプローチでキャッシュなしで依存関係をインストールします。 11秒 yarn が 使用されたコマンド: yarn install --frozen-lockfile グローバルキャッシュを使用して既存のロックファイルから依存関係をインストールする かかった 「ゼロ インストール」アプローチとグローバル キャッシュを使用して依存関係をインストールします。 8秒 yarn が 使用されたコマンド: yarn install --frozen-lockfile ワークスペースの管理 を作成し、すべてのプロジェクトの依存関係を一度に管理したり、特定のプロジェクトの依存関係を個別に管理したりできるようになりました。 ワークスペース これまで使用したワークスペース機能: ワークスペース内のすべてのプロジェクトの依存関係をインストールします。 特定の単一のプロジェクトの依存関係をインストールします。 すべてのプロジェクトに対して単一のスクリプトを一度に再帰的に実行します。 ドキュメントは問題ありませんが、コマンド名とフラグがややわかりにくいです。 たとえば、 ( ) およびネストされた プロジェクトで スクリプトを実行するには、これを実行する必要があります。 ルート . b2b test yarn workspaces foreach -A --include '{.,b2b}' run test との比較: npm npm run test --workspace=b2b --include-workspace-root ピンポン は現在話題になっており、 。 pnpm 多くの企業やオープンソース プロジェクトで使用されています と同様に、 には インストーラーが付属していないため、別途インストールする必要があります。つまり、 パイプラインに追加の手順が必要になります。つまり、プロジェクトの依存関係をインストールする前に をセットアップする必要があります。 yarn pnpm Node.js CI pnpm 依存関係の管理 と考えられています... pnpm は 「 」 高速でディスク容量効率の良いパッケージ マネージャー 確かに、依存関係をローカルで管理するという点では、 という意見に同意します。 「ディスク スペース効率が良い」 デフォルトでは、 共有依存関係の重複を排除します。pnpm 、複数の依存関係で使用されるパッケージのシンボリックリンクを作成します。つまり、パッケージ と がパッケージ を依存関係として使用する場合、 パッケージ 単一のコピーとして保存し、パッケージ と のシンボリックリンクを作成します。こうすることで、パッケージ マネージャーはハード コピーを作成せず、SSD/HDD のメモリを節約します。 pnpm は は a b c pnpm は c a b ℹ️ リストされているパッケージのレジストリに関する情報は保存されません。 pnpm-lock.yaml ⚠️ 依存関係をプロジェクトとして保持するのではなく、グローバル キャッシュに保存することがあることに留意してください。 pnpm は キャッシュなしでpnpm-lock.yamlを生成する かかった を生成し、キャッシュなしで依存関係をインストールします。 31秒 pnpm が pnpm-lock.yaml 使用されたコマンド: pnpm install グローバルキャッシュなしで pnpm-lock.yaml から依存関係をインストールする かかった キャッシュなしで から依存関係をインストールします。 16秒 pnpm が pnpm-lock.yaml 使用されたコマンド: pnpm i --frozen-lockfile グローバル キャッシュを使用して既存のロック ファイルから依存関係をインストールする かかった がグローバル キャッシュを使用して から依存関係をインストールします。 5秒 pnpm pnpm-lock.yaml 使用されたコマンド: pnpm i --frozen-lockfile ワークスペースの管理 さて、ここからが本当に面白くなってくるのですが… には多くの設定オプションがありますが、一部のコア機能は動作しません。 pnpm 私が直面したバグをいくつか見てみましょう: pnpm インストール --filter 特定のプロジェクトのみの依存関係をインストールできることは重要です。これは、ワークスペース内の特定のプロジェクトに関連するパイプラインを作成するときに、モノレポに非常に役立ちます。 つまり、ワークスペースに次のようなものがあると想像してください。 ウェブアプリ、 バックエンドサーバー、 テスト プロジェクト (エンドツーエンド テスト)。 これらはすべて別々の プロジェクトですが、同じリポジトリの一部です ☝️ npm ここで、パイプラインでエンドツーエンドのテストのみを実行する必要があります。つまり、エンドツーエンドのテスト依存関係のみが必要なわけですね。 まあ、それはできません - ワークスペース全体の依存関係をインストールするように強制します。 pnpm は 、選択したプロジェクトの依存関係のみをインストールするはずでしたが、機能しません。 pnpm install --filter <project-name> 1 年前のバグがあり、最近、機能しない修正で閉じられました。 再帰インストール=false はデフォルトで 実行するとワークスペース全体(すべてのプロジェクト)の依存関係をインストールします。 pnpm pnpm install ワークスペース ルートの で 設定すると、この動作を切り替えることができます。 .npmrc recursive-install=false しかし、 。 それはすでにほぼ 2 年前の別のバグを導入します 共有ワークスペースロックファイル=false デフォルトで依存関係リストを単一のロック ファイルに保存します ( および と同じ)。 pnpm は npm yarn ワークスペース ルートの で を設定すると、この動作を変更することもできます。 .npmrc shared-workspace-lockfile=false これにより、ワークスペース機能を維持し、 フラグを使用して特定のプロジェクトの依存関係をインストールできるようになります。 --ignore-workspace いずれにせよ、この設定により、さらにいくつかの問題が発生します。 と パイプラインで エラーをスローします。 eslint tsc --noEmit GitHub Actions 「JavaScript ヒープ メモリ不足」 依存関係の一部はグローバル キャッシュに保存され、 にシンボリック リンクされます。 node_modules/.pnpm パフォーマンス比較結果 # ネプ 糸 ピンポン ロックファイルを生成する 60秒 16.5秒 31秒 キャッシュなしで依存関係をインストールする 18秒 11秒 8秒 グローバルキャッシュを使用して依存関係をインストールする 8秒 8秒 5秒 上記のベンチマークによると、 最も遅いパッケージ マネージャーです ☝️ npm は とにかく、これらの結果を解釈してみましょう... ロックファイルを生成する これはまれなケースです。通常、ロック ファイルはプロジェクトの初期化時に作成され、パッケージをインストール/更新するときに拡張されます。 それを念頭に置くと、パッケージ マネージャーを選択するときに頼るべきことはそれほど重要ではないようです。 依存関係をインストールする ほとんどの場合、プロジェクトは特定の依存関係のリストを保持しており、何かを追加/削除することはほとんどありません。 おそらく、パッケージのバージョンは時々変更されるでしょう。これらの変更は小さく、残りのパッケージはキャッシュから再利用されます。 つまり、一般的な使用例は、パッケージ レジストリから新しいパッケージを取得し、残りをキャッシュから取得することです。 (5〜8 秒) は (8〜18 秒) のほぼ 2 倍の速度で、 (8〜11 秒) が中間です。 pnpm npm yarn 結論 事実 確かに パッケージ マネージャーです。これは現在のレビューでも明らかです。 pnpm は 「高速でディスク効率の良い」 ワークスペース機能にはバグがあり、そのバグのいくつかは何年も解決されていません。 pnpm と どちらも CI パイプラインで追加の設定が必要ですが、 必要ありません。 pnpm yarn は npm では と どちらもロック ファイルにパッケージ レジストリ情報を保存しませんが、 保存します。 pnpm yarn は npm は 著者の考え パッケージ マネージャーに対する要件が「依存関係のみをインストールする」という単純なものである場合は、 が最適だと思います。 pnpm にはすぐに使える インストーラーが付属していませんが、 または を使用して CI パイプラインで簡単にセットアップできます。 pnpm Node.js corepack 既存の action 私は を好みます。その理由は次のとおりです: npm 安定している(特にワークスペース) に付属しており、CIパイプラインで追加の設定は必要ありません。 Node.js パッケージ レジストリを に保存するので、異なるレジストリから単一のスコープで依存関係をインストールできます。 package-lock.json これらの利点は、 や で節約できる数秒の速度とディスク容量を上回ります。 yarn pnpm パッケージ マネージャーを選択する際の基準は何ですか? 遠慮せずに、下のコメント セクションであなたの考えを教えてください! 👇😊