ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript パッケージマネージャーの比較: Npm vs Yarn vs Pnpm

JavaScript パッケージマネージャーの比較: Npm vs Yarn vs Pnpm

青灯夜游
青灯夜游転載
2022-08-09 16:22:513240ブラウズ

この記事では、3 つの JavaScript パッケージ マネージャー (npm、yarn、pnpm) について説明し、これら 3 つのパッケージ マネージャーを比較し、npm、yarn、pnpm の違いと関係について説明します。 . ご不明な点がございましたら、ご指摘ください。

JavaScript パッケージマネージャーの比較: Npm vs Yarn vs Pnpm

#パッケージ マネージャー分野の 3 つの主要プレーヤー:

  • npm

  • Yarn

  • 高性能 npm (pnpm)

私たちは実際には、すべてのパッケージ マネージャーに基本的に同様の機能が実装されているため、インストール速度、ストレージ消費量、実用性など、機能以外の要件に基づいてどのパッケージ マネージャーを使用するかを決定することになるでしょう。

もちろん、各パッケージ マネージャーの使用方法は異なりますが、基本的にはすべて同じ概念を持っています。上記のパッケージ マネージャーはすべて、次の命令を実行できます。

    データの読み取りと書き込み
  • すべての依存関係をバッチでインストールまたは更新
  • 依存関係を追加、更新、および削除
  • スクリプトを実行します
  • パッケージを公開します
  • #ただし、それにもかかわらず、パッケージ マネージャーは内部的に異なります。従来、
npm

Yarn には、フラットな node_modules フォルダー に依存関係がインストールされています。 (ここでの順序に注意してください。yarn が最初にタイル化され、その後 npm が再帰的になります)。しかし、タイル張りは一連の安全上の問題を引き起こす可能性もあります。

    依存関係構造の不確実性
  • 平坦化アルゴリズム自体は
  • 複雑度
  • 非常に高く、時間がかかります。

    #プロジェクトは引き続き

    不正アクセス
  • ##宣言された依存関係を持つパッケージ

  • # したがって、

    pnpm

    では、依存関係をより効率的に保存するために、
  • node_modules
フォルダーにいくつかの新しい概念が導入されています。
Yarn Berry

は、node_modules の (PnP) モードを完全に放棄することでさらに進んでいます (これについては別の記事で詳しく説明します)。 JavaScript パッケージの簡単な歴史

最初にリリースされたパッケージ マネージャーは、2010 年 1 月には

npm でした。これは、今日のパッケージ マネージャーがどのように機能するかの中核となる原則を確立しました。しかし、npm

は 10 年以上存在しているのに、なぜ他に選択肢があるのでしょうか?これが起こる主な理由は次のとおりです。

node_modules フォルダー構造の依存関係解決アルゴリズムが異なる (ネストおよびフラット、
node_modules

と PnP の比較)モード)
  • さまざまな依存関係ホイスティング方法 (ホイスティング)
  • ロック
  • さまざまな形式 (さまざまなパフォーマンス (yarn など)
  • ディスク ストレージ パッケージ ファイルの方法が異なる (スペース効率が異なる) マルチパッケージ プロジェクト ( ワークスペース とも呼ばれます) サポートが異なり、保守性に影響します
  • monorepos
  • 新しいツールやコマンドに対するさまざまなニーズ (プラグインやコミュニティ ツールによる拡張性に対するさまざまなニーズ)構成可能性と柔軟性は異なります
  • npm
  • の台頭後にこれらの側面がどのように決定されたか、そして
  • Yarn Classic
  • がそれらをどのように解決したかの歴史を詳しく見てみましょう
pnpm の方法に関するいくつかの質問

はこれらの概念を拡張し、Yarn Classic の後継者である Yarn Berry がこれらの従来の概念とプロセスをどのように打ち破るかを説明します。 Pioneer npm

npm

は、パッケージ マネージャーの元祖です。多くの人が npm が「Node package manager」の頭字語であると誤解していますが、そうではありません。 以前はプロジェクトの依存関係を手動でダウンロードして管理していたため、このリリースは革命をもたらしました。

npm

では、ファイルとそのメタデータ フィールド、node_modules への依存関係の保存、カスタム スクリプト、パブリックおよびプライベート パッケージなどを導入します。 2020 年に GitHub が npm を買収したため、原則として

npm

は Microsoft によって管理されるようになりました。この記事の執筆時点では、最新メジャー バージョンは v8 で、2021 年 10 月にリリースされています。 <h3 data-id="heading-2"><strong>Innovator Yarn Classic</strong></h3> <p>2016 年 10 月、Facebook は、新しいパッケージ マネージャーを開発するために Google および他の多くの企業と提携することを発表しました (<a href="https://engineering.fb.com/2016/10/11/web/yarn-a-new-package-manager-for-javascript/" target="_blank" textvalue="engineering.fb.com/2016/10/11/…">engineering.fb.com / 2016/10/11/…</a>) は、当時 npm に存在していた一貫性、セキュリティ、パフォーマンスの問題に対処します。彼らは、代替品を <a href="https://classic.yarnpkg.com/lang/en/" target="_blank" textvalue="Yarn">Yarn</a> と名付けました。 </p> <p><code>Yarn は依然として npm の多くの概念とプロセスに基づいて設計および構築されていますが、Yarn は依然として次の分野に大きな影響を与えています。パッケージマネージャーの影響。 Yarn は操作を並列化して、npm と比較してインストール プロセスを高速化します。これは、npm の以前のバージョンの大きな問題点でした。

Yarn は、読み取りと書き込み、セキュリティとパフォーマンスに関するより高い標準を設定し、次のような多くの概念を考案しました (後に npm もこれについて多くの改良を加えました):

  • monorepo サポート
  • キャッシュのインストール
  • オフライン ダウンロード
  • ファイル ロック (ロック )

Yarn v1 2020 年にメンテナンス モードに入りました#。それ以来、v1.x シリーズはレガシーとみなされ、Yarn Classic に名前が変更されました。その後継となる Yarn v2 (Berry) は、現在、より活発な開発ブランチです。

より効率的

pnpm

pnpm

Zoltan Kochan による初版、2017 年にリリース。これは npm の代替となるため、npm プロジェクトがある場合は、すぐに pnpm を使用できます。

pnpm

を作成する主な理由は、npmYarn がプロジェクト間で使用される依存関係のストレージ構造にとって非常に冗長であるためです。 Yarn Classicnpm よりも速度の面で優れていますが、pnpm では不可能な同じ依存関係解決方法を使用します: npmYarn Classic は、前の構造を最適化せずに hoisting を使用して node_modules.

pnpm

をタイリングしますが、別の構造が導入されます。依存関係解決戦略: コンテンツ アドレス指定を備えたストレージ構造。このメソッドで生成された node_modules フォルダーは、実際には、メイン フォルダーにグローバルに保存されている ~/.pnpm-store/ ディレクトリに依存します。依存関係の各バージョンは、このディレクトリ フォルダーに物理的に一度保存され、単一のソース アドレスを形成して、ディスク領域を大幅に節約します。

node_modules

構造は、symlinks を使用して作成された依存関係のネストされた構造です (フォルダー内の各ファイル/パッケージは ハード リンクStorage) 公式ドキュメントの次の画像は、これを示しています。 (記入予定: ソフトリンクとハードリンク)

JavaScript パッケージマネージャーの比較: Npm vs Yarn vs Pnpm

pnpm の影響は 2021 年のレポートで確認できます: なぜなら彼らは コンテンツ アドレス可能ストレージのイノベーションに取り組んでおり、競合他社は シンボリック リンクの構造やパッケージの効率的なディスク管理などの pnpm 概念の採用を検討しています。 Yarn (v2、Berry)、プラグアンドプレイによる車輪の再発明

Yarn 2

は 2020 年 1 月にリリースされ、オリジナルの ## A として昇格されました。 #Yarn のメジャー アップグレード。 Yarn チームは、本質的に新しいコード ベースと新しい原則仕様を備えた新しいパッケージ マネージャーであることをより明確にするために、これを Yarn Berry と名付けました。

Yarn Berry の主な革新は、プラグ アンド プレイ (PnP) アプローチであり、node_modules を修復するための 戦略として機能します。 node_modules を生成する戦略の代わりに、依存関係ルックアップ テーブルを含むファイル .pnp.cjs を生成します。これは、ネストされたフォルダー構造ではなく単一のファイルであるため機能します。依存関係をさらに処理します。効率的に。さらに、各パッケージは .yarn/cache/ ではなく zip ファイル としてフォルダーに保存され、占有ディスク容量は node_modules よりも少なくなります。

これらの変更はすべて非常に迅速に行われたため、リリース後に多くの論争を引き起こしました。 PnP に対するこのような重大な変更を行うには、保守者は既存のパッケージ を更新して互換性を持たせる必要があります。デフォルトで新しい PnP アプローチを使用し、node_modules に戻すことは最初は簡単ではありませんでした。そのため、多くの著名な開発者がそれを検討せず、 Yarn 2 を公に批判しました。

それ以来、Yarn Berry チームは、その後のリリースで多くの問題を 解決してきました。 PnP の非互換性の問題を解決するために、チームはデフォルトの動作モードを簡単に変更する方法を提供しました。 node_modules プラグイン を使用すると、1 行の設定のみで従来の node_modules 方式に切り替えることができます。

さらに、JavaScript エコシステムは時間の経過とともに PnP のサポートをますます提供してきました。この 互換性表 でわかるように、いくつかの 大規模 プロジェクトYarn Berryの採用を開始しました。

Yarn Berry はまだ若いですが、すでにパッケージ マネージャー領域に影響を与えています - pnpmPnP アプローチを 2020 年後半に採用しました ## #。

インストール ワークフロー

まず、パッケージ マネージャーを各開発者のローカル システムおよび CI/CD システムにインストールする必要があります。


npm

npm

には Node.js が同梱されているため、追加の手順は必要ありません。オペレーティング システムの Node.js インストーラー をダウンロードすることに加えて、CLI ツールを使用してソフトウェア バージョンを管理することが一般的になってきています。 Node のコンテキストでは、Node Version Manager (nvm) または Volta が非常に便利なユーティリティになっています。

Yarn Classic と Yarn Berry

Yarn 1

は、

npm など、さまざまな方法でインストールできます。パッケージをインストールするには: .$ npm i -gyarn Yarn Classic から Yarn Berry

に移行するには、推奨される方法は次のとおりです:

Yarn Classic
    を最新バージョンにインストールまたは更新します
  • コマンドを使用して最新バージョンにアップグレードします

    yarn set version berry
  • ただし、Yarn Berry

    をインストールする
  • 推奨方法は Corepack を使用することです。

Corepack是由 Yarn Berry 的开发者创建的。该计划最初被命名为包管理器管理器(pmm) ?,并在 LTS v16 中与 Node 合并。

在 Corepack 的帮助下,因为 Node 包含 Yarn ClassicYarn Berrypnpm 二进制文件所以您不必“单独”安装的 npm 的替代包管理器。这些垫片允许用户运行 Yarn 和 pnpm 命令而无需先显式安装它们,也不会弄乱 Node 发行版。

Corepack 预装了 Node.js ≥ v16.9.0。但是,对于较旧的 Node 版本,您可以使用⬇️

npm install -g corepack

在使用之前先启用 Corepack。该示例显示了如何在 Yarn Berry v3.1.1 中激活它。

# you need to opt-in first
$ corepack enable
# shim installed but concrete version needs to activated
$ corepack prepare yarn@3.1.1 --activate

pnpm

您可以将 pnpm 作为 npm包来安装: $ npm i -g pnpm。您还可以使用 Corepack 安装 pnpm : 

$ corepack prepare pnpm@6.24.2 --activate

项目结构


在本节中,您将一目了然地看到不同包管理器的主要特征。您可以轻松发现配置特定包管理器涉及哪些文件,以及哪些文件是由安装步骤生成的。

所有包管理器都将所有重要的元信息存储在项目清单package.json文件中。 此外,根级别的配置文件可以被用来设置不同的私有包或者不同的依赖项解析配置。

在安装步骤中,依赖项 dependencies 被存储在文件结构中,例如 node_modules 并生成锁定文件 locking。本节不考虑工作区设置,因此所有示例仅显示存储依赖项的单个位置。

npm

使用$ npm install 或较短的 $ npm i 会生成一个 package-lock.json 文件和一个 node_modules 文件夹。还有 .npmrc 这种可配置的文件可以放在根级别目录里面。有关 locking 文件的更多信息,请参阅下一节。

.
├── node_modules/
├── .npmrc
├── package-lock.json
└── package.json

yarn

运行 $ yarn 会创建一个 yarn.lock 文件和一个 node_modules 文件夹。.yarnrc 文件也可以是配置的选项,Yarn Classic 也支持 .npmrc 文件。或者可以使用缓存文件夹 .yarn/cache/ 和本地存储的最近的 Yarn Classic 版本 .yarn/releases/

.
├── .yarn/
│   ├── cache/
│   └── releases/
│       └── yarn-1.22.17.cjs
├── node_modules/
├── .yarnrc
├── package.json
└── yarn.lock

yarn berry: node_modules

因为这种特殊的安装模式,比使用其他包管理器您必须在 Yarn Berry 项目中处理更多的文件和文件夹。有些是可选的,有些是强制性的。

Yarn Berry 不再支持 .npmrc 或者 .yarnrc;他需要一个 .yarnrc.yml。对于传统的生成 node_modules 文件夹的工作流程,您必须提供 nodeLinker 配置来使用 node_modules 或者 pnpm 的配置(这块没看懂)。

# .yarnrc.yml
nodeLinker: node-modules # or pnpm

运行 $ yarn 会将所有依赖项安装在一个 node_modules 文件夹中。并且生成一个 yarn.lock 文件,该文件较新但与 Yarn Classic 不兼容。此外,还会生成一个用于离线安装的 .yarn/cache/ 文件夹。该文件夹是可选的,用于存储项目使用的 Yarn Berry 版本。

.
├── .yarn/
│   ├── cache/
│   └── releases/
│       └── yarn-3.1.1.cjs
├── node_modules/
├── .yarnrc.yml
├── package.json
└── yarn.lock

yarn berry: pnp

无论是对于PnP 的严格模式还是松散模式,跟着 .pnp.cjsyarn.lock 来执行 $ yarn 都会生成一个 .yarn/cache/ 还有 .yarn/unplugged。PnP strict 是默认模式,如果想要配置 loose 模式,需要如下形式开启⬇️:

# .yarnrc.yml
nodeLinker: pnp
pnpMode: loose

在 PnP 项目中,除了 releases 文件夹之外,.yarn 文件夹很可能还包含一个提供IDE 支持的 sdk/ 文件夹。根据您的用例,.yarn 甚至可以包含更多的文件夹。

.
├── .yarn/
│   ├── cache/
│   ├── releases/
│   │   └── yarn-3.1.1.cjs
│   ├── sdk/
│   └── unplugged/
├── .pnp.cjs
├── .pnp.loader.mjs
├── .yarnrc.yml
├── package.json
└── yarn.lock`

pnpm

npmYarn Classic 项目的初始状态一样,pnpm 也需要 package.json 文件。使用 $ pnpm i 安装依赖项后,会生成一个 node_modules 文件夹,但由于其内容是可寻址存储方式,其结构完全不同。

pnpm 还会生成自己的锁定文件 pnp-lock.yml。 您可以使用可选文件 .npmrc 提供附加配置。

.
├── node_modules/
│   └── .pnpm/
├── .npmrc
├── package.json
└── pnpm-lock.yml

锁定文件和依赖存储


如上一节所述,每个包管理器都会创建锁定文件

lock 文件准确存储您的项目安装的每个依赖项的版本从而实现更可预测和确定性的安装。因为依赖版本很可能使用版本范围声明(例如,≥ v1.2.5)所以这个 lock 文件是很重要的,如果您不“lock”您的版本,实际安装的版本可能会有所不同。

锁定文件有时也存储校验和(我记得是一段hash),我们将在安全部分更深入地介绍。

npm v5+ 开始锁定文件一直是 npm 主要的功能 ( package-lock.json ) ,pnpm 里是 pnpm-lock.yaml ,在 Yarn Berry 中的 yarn.lock 以新的 YAML 格式出现。

在上一节中,我们看到了传统方法,将依赖项安装在 node_modules 文件夹结构中。这是 npmYarn Classicpnpm都使用的方案,(其中 pnpm 比其他方案更有效)。

Yarn Berry 在 PnP 模式下的做法有所不同。依赖项不是 node_modules 文件夹,而是以 zip 文件的形式存储为 .yarn/cache/.pnp.cjs 文件的组合。

最好将这些锁定文件置于版本控制之下,因为每个团队成员都安装相同的版本,所以它解决了“在你和我的机器上工作”问题。

CLI


下表比较了 npmYarn ClassicYarn Berrypnpm 中可用的不同 CLI 命令。这绝不是一个完整的列表,而是一个备忘单。本节不涉及与workflow 相关的命令。

npmpnpm 具有许多特别的命令和选项别名,这意味着命令可以有不同的名称,即$ npm install$ npm add。 此外,许多命令选项都有缩写版本,例如 -D 来代替 --save-dev。 在表格中,我将所有缩写版本称为别名。使用这些包管理器,您都可以增加、更新或删除多个依赖项。

依赖配置管理

此表涵盖了用于安装或更新 package.json 中指定的所有依赖项的依赖项管理命令。

#アクションnpmヤーン クラシックヤーン ベリーpnpmpackage.json に deps をインストールします。npm install エイリアス: i、addyarn install またはyarnlike Classicpnpm インストール エイリアス: ipackage.json の deps を更新します。 semvernpm update alias: up、upgradeyarn upgradeyarn semver up (via pnpm update alias : uppackage.json の deps を最新のN/Ayarn upgrade --latestyarn up# に更新しますupdate deps acc. semver depsを最新のdeps を対話的に更新しますpluginランタイム deps を追加add dev depssemver なしで package.json に deps を追加します。deps をアンインストールし、package.json から削除しますpackage.json を更新せずに deps をアンインストールします
plugin)
##pnpm update --latest エイリアス: -L
npm更新react yarnアップグレードreact yarn semverアップreact pnpmアップreact
npmに更新しますreact@latest yarnアップグレードreact --latest yarn upreact pnpm up -Lreact
N/A yarn upgrade-interactive yarn upgrade-interactive ( 経由) $ pnpm up --interactive エイリアス: -i
npm i 反応 yarn 反応を追加 like Classic pnpm add react
npm i -D babel エイリアス: --save-dev yarn add -D babel alias: --dev like Classic pnpm add -D babel alias: --save-dev
npm i -E 反応エイリアス: --save-exact yarn add -E 反応エイリアス: --exact like Classic pnpm add -E accept alias: --save-exact
npm アンインストール反応エイリアス:remove、rm、r、un、unlink yarn 反応を削除 like Classic pnpm 反応エイリアスを削除: rm、un、uninstall
npm uninstall --no-save N/A N/A N/A
インストール構成管理

次の例は、公開中にパケットを管理する方法を示しています。 :

パッケージ: 依存関係またはバイナリ
  • バイナリ:
  • node_modules/.bin/
  • または .yarn/cache からの 1 つの実行ツール/ (PnP)
重要な点をご理解ください。
Yarn Berry

package.json で実行するだけです。 bin/ ファイル内に指定​​された 2 つの二重化ファイル。

Actionパッケージをグローバルにインストールnpm i -g ntl エイリアス: --global yarn global add ntlN/A ()パッケージをグローバルに更新しますnpm update -g ntlyarn グローバル アップグレード ntlN/Apnpm update --global ntlパッケージをグローバルに削除npm uninstall -g ntlyarn グローバル削除 ntlN/Apnpm 削除 - -global ntlターミナルからバイナリを実行npm exec ntlyarn ntlyarn ntl pnpm ntlスクリプトからバイナリを実行ntlntlntlntl動的パッケージの実行npx ntlN/Ayarn dlx ntlpnpm dlx ntlランタイム deps を追加npm 私は反応しますyarn 反応を追加しますClassic のようなpnpm 反応を追加しますadd dev depsnpm i -D babel エイリアス: --save-devyarn add -D babel エイリアス: --dev Classicpnpm add -D babel alias: --save-devsemver なしで package.json に deps を追加npm i -E反応エイリアス: --save-exactyarn add -E 反応エイリアス: --exactlike Classicpnpm add -E 反応エイリアス: --save-exact deps をアンインストールし、package.json から削除しますnpm アンインストール反応エイリアス: 削除、rm、r、un、unlinkyarn 反応エイリアスを削除しますlike Classicpnpm 反応エイリアスを削除: rm、un、uninstallpackage.json を更新せずに deps をアンインストールnpm uninstall --no-saveN/AN/AN/A

一般的に使用されるコマンド

この表では、いくつかの便利な組み込みコマンドについて説明します。公式コマンドがない場合は、通常、npm パッケージまたは Yarn Berry プラグインを通じてサードパーティのコマンドを使用できます。

npm Yarn Classic Yarn Berry pnpm
global selectedpnpm add --global ntl
#アクションnpmヤーン クラシックヤーン ベリーpnpm出版包npm publishyarn publishyarn npm publishpnpm publishインストールされている depsnpm ls エイリアスをリストします: list、la、llyarn list #pnpm list エイリアス: ls##list outdated depsdeps に関する情報を出力しますinit プロジェクトライセンス情報の印刷plugin##パッケージ マネージャーのバージョンの更新N/A (サードパーティ ツール (例: nvm) npm Auditnpm i -E 反応エイリアス: --save-exactnpmアンインストール反応エイリアス:remove、rm、r、un、unlinknpm uninstall --no-save

npm outdated yarn outdated yarn upgrade-interactive pnpm は古いです
npm ntl エイリアスを説明します: Why yarn Why ntl like Classic pnpm なぜ ntl
npm init -y npm init (対話型) エイリアス: --yes yarn init -yyarn init (対話型) エイリアス: --yes yarn init pnpm init -y pnpm init (対話型) エイリアス: --yes
N/A (サードパーティ パッケージ経由) 糸ライセンス リスト N/A (または 経由)他の plugin)N/A (サードパーティ パッケージ経由)
#npm の場合: 糸ポリシー セット バージョン 1.13.0 コアパックの場合: 糸セット バージョン 3.1.1 N/ (npm、Corepack を使用) セキュリティ監査を実行します
yarn Audit yarn npm Audit pnpm Audit semver を使用せずに package.json に deps を追加します
yarn add -E 反応エイリアス: --exact like Classic pnpm 追加 -E 反応エイリアス: --save-exact deps をアンインストールし、 package.jsonから削除
yarn削除react like Classic pnpm削除反応エイリアス: rm、un、uninstall package.jsonの更新なしでdepsをアンインストール
N /A N/A N/A

配置文件


配置包管理器发生在您的 package.json 和专用的配置文件中。

  • 定义要使用的准确版本
  • 使用特定的依赖解决策略
  • 配置私有注册表
  • 告诉包管理器在哪里可以找到 monorepo 中的工作区

npm

大多数配置发生在专用配置文件 .npmrc 中。

如果你想使用 npmworkspaces 功能,你必须在 package.json 中添加workspaces 元数据字段来告诉 npm 在哪里可以找到子项目或工作空间的文件夹。

  // ...
  "workspaces": [
    "hooks",
    "utils"
  ]
}

每个包管理器都可以使用公共 npm 注册表。或许你很可能希望重用它们而不将它们发布到公共注册表。您可以在 .npmrc 文件中执行此操作配置来私有注册表。( 现在基本都有私有源了)

# .npmrc
@doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/

npm 存在许多配置选项,最好在文档中查看它们。\

yarn

您可以在 package.json 中设置 yarnworkspaces(必须是私有包)。

{
  // ...
  "private": true,
  "workspaces": ["workspace-a", "workspace-b"]
}

任何可选配置都进入一个 .yarnrc 文件。一个常见的配置选项是设置一个 yarn-path: 它强制每个团队成员使用指定的二进制版本。yarn-path 指向包含特定 Yarn 版本的文件夹(例如 .yarn/releases/)。您可以使用命令来安装统一的 Yarn Classic 版本(classic.yarnpkg.com/en/docs/cli…)。

yarn berry

Yarn Berry 中配置 workspaces 和在 Yarn Classic 中的配置方式类似(package.json)。 大多数 Yarn Berry 配置发生在 .yarnrc.yml 中,并且有许多可用的配置选项。

# .yarnrc.yml
yarnPath: .yarn/releases/yarn-3.1.1.cjs

yarn berry可以用 $> yarn plugin import <name></name> 这种导入方式来扩展插件(yarnpkg.com/cli/plugin/…),这个命令也会更新 .yarnrc.yml

# .yarnrc.yml
plugins:
  - path: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs
    spec: "https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js"

如历史部分所述,因为兼容性的关系,PnP 严格模式下的依赖关系可能存在某些问题。此类 PnP 问题有一个典型的解决方案:包扩展配置策略

# .yarnrc.yml
packageExtensions:
  "styled-components@*":
    dependencies:
      react-is: "*"

pnpm

pnpm 使用与 npm 相同的配置机制,因此您可以使用 .npmrc 文件。配置私有注册表的工作方式也与使用 npm 相同。借助 pnpm 的工作空间功能可以支持多包项目。要初始化 monorepo,您必须在 pnpm-workspace.yaml 文件中指定包的位置

# pnpm-workspace.yaml
packages:
  - 'packages/**'

Monorepo


什么是Monorepo

(这里其实就是三种概念,单仓库多项目,单仓库单项目,多仓库多项目)

monorepo 是一个包含多个项目的存储库,这些项目被称为 workspace 或者包。将所有内容保存在一个地方而不是使用多个存储库是一种项目组织策略。

当然,这会带来额外的复杂性。Yarn Classic 是第一个启用此功能的,但现在每个主要的包管理器都提供了工作区功能。本节展示如何使用每个不同的包管理器配置工作区。

npm

npm 团队在 v7 中发布了期待已久的npm 工作区功能。它包含许多 CLI 命令,可帮助从根包中管理多包项目。大多数命令可以与 workspace 相关的选项一起使用以告诉 npm 它是否应该针对特定、多个或所有工作空间运行。

# Installing all dependencies for all workspaces
$ npm i --workspaces.
# run against one package
$ npm run test --workspace=hooks
# run against multiple packages
$ npm run test --workspace=hooks --workspace=utils
# run against all
$ npm run test --workspaces
# ignore all packages missing test
$ npm run test --workspaces --if-present

tips: 与其他包管理器相比,npm v8 目前不支持高级过滤或并行执行多个与工作区相关的命令。

yarn

2017 年 8 月,Yarn 团队宣布在workspace功能方面提供 monorepo 支持。在此之前,只能在Lerna等第三方软件的多包项目中使用包管理器。Yarn 的这一新增功能也为其他包管理器实现此类功能铺平了道路。

如果你有兴趣,可以参考如何在有和没有 Lerna 的情况下使用 Yarn Classic 的工作区功能。但是这篇文章只会介绍一些必要的命令,以帮助您管理 Yarn Classic 工作区设置中的依赖关系。

# 为所有工作空间安装所有依赖项
$ yarn 
# 显示依赖关系树
$ yarn workspaces info 
# 再一个包运行启动
$ yarn workspace awesome - package start
  # 将Webpack添加到包
$ yarn workspace awesome - package add - D webpack
  # add React 对所有包
$ yarn add react -W

yarn berry

Yarn Berry 从一开始就以工作区为特色,因为它的实现是建立在 Yarn Classic 的概念之上的。在Reddit 评论中,Yarn Berry 的主要开发人员简要概述了面向工作空间的功能,包括:

Yarn Berry 使用大量可用于 package.json 文件的 dependenciesdevDependencies 字段的协议。其中就有 workspace协议

Yarn Classic 的工作区相比,Yarn Berry 明确定义依赖项必须是此 monorepo 中的包之一。否则如果版本不匹配,Yarn Berry 可能会尝试从远程注册表获取其版本。

{
  // ...
  "dependencies": {
    "@doppelmutzi/hooks": "workspace:*",
    "http-server": "14.0.0",
    // ...
  }  
}

pnpm

通过 workspace 这种协议,pnpm 促成了类似于 Yarn Berrymonorepo 项目。许多 pnpm 命令接受 --recursive (-r) 或者 --filter 这种在 monorepo 上下文中特别有用的选项。它的原生过滤命令也是对 Lerna 的一个很好的补充。

# prune all workspaces  
pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml  
# run all tests for all workspaces with scope @doppelmutzi
pnpm recursive run test --filter @doppelmutzi/`

性能 & 磁盘效率


性能是选型决策的关键部分。本节展示了基于一个小型和一个中型项目的基准测试。以下是有关示例项目的一些说明:

  • 两组基准都不使用工作区功能
  • 小项目指定33个依赖
  • 中项目指定44个依赖

我用三个用例 (UC) 对我们的每个包管理器变体进行了一次测量。要了解详细的评估和解释,请查看项目 1 (P1)项目 2 (P2)的结果。

  • UC 1:没有缓存/存储,没有锁定文件,没有 node_modules.pnp.cjs
  • UC 2:存在缓存/存储,没有锁定文件,没有 node_modules.pnp.cjs
  • UC 3:存在缓存/存储,存在锁定文件,没有 node_modules.pnp.cjs

我使用工具gnomon来测量安装消耗的时间( yarn | gnomon )。此外我测量了生成文件的大小 $ du -sh node_modules

Performance results for Project 1






Method npm v8.1.2 Yarn Classic v1.23.0 pnpm v6.24.4 Yarn Berry PnP loose v3.1.1 Yarn Berry PnP strict v3.1.1 Yarn Berry node_modules v3.1.1 Yarn Berry pnpm v3.1.1
UC 1 86.63s 108.89s 43.58s 31.77s 30.13s 56.64s 60.91s
UC 2 41.54s 65.49s 26.43s 12.46s 12.66s 46.36s 40.74s
UC 3 23.59s 40.35s 20.32s 1.61s 1.36s 28.72s 31.89s
Files and size package-lock.json: 1.3M node_modules: 467M node_modules: 397M yarn.lock: 504K pnpm-lock.yaml: 412K node_modules: 319M yarn.lock: 540K cache: 68M unplugged: 29M .pnp.cjs: 1.6M yarn.lock: 540K cache: 68M unplugged: 29M .pnp.cjs: 1.5M node_modules: 395M yarn.lock: 540K cache: 68M node_modules: 374M yarn.lock: 540K cache: 68M
Performance results for Project 2






Method npm v8.1.2 Yarn Classic v1.23.0 pnpm v6.24.4 Yarn Berry PnP loose v3.1.1 Yarn Berry PnP strict v3.1.1 Yarn Berry node_modules v3.1.1 Yarn Berry pnpm v3.1.1
UC 1 34.91s 43.26s 15.6s 13.92s 6.44s 23.62s 20.09s
UC 2 7.92s 33.65s 8.86s 7.09s 5.63s 15.12s 14.93s
UC 3 5.09s 15.64s 4.73s 0.93s 0.79s 8.18s 6.02s
Files and size package-lock.json: 684K node_modules: 151M yarn.lock: 268K node_modules: 159M pnpm-lock.yaml: 212K node_modules: 141M .pnp.cjs: 1.1M .pnp.loader.mjs: 8.0K yarn.lock: 292K .yarn: 38M .pnp.cjs: 1.0M .pnp.loader.mjs: 8.0K yarn.lock: 292K .yarn: 38M yarn.lock: 292K node_modules: 164M cache: 34M yarn.lock: 292K node_modules: 156M cache: 34M

セキュリティ


npm

##npm これに関しては、少し寛容すぎます。パッケージに問題があり、多くのプロジェクトに直接影響を与えるセキュリティ上の脆弱性が発生しました。たとえば、バージョン 5.7.0 では、Linux オペレーティング システムで sudo npm コマンドを実行すると、システム ファイルの所有権が変更され、オペレーティング システムが使用できなくなる可能性があります。

ビットコインの盗難に関する別の事件

が2018年に発生しました。 Node.js パッケージ EventStream には、バージョン 3.3.6 に悪意のある依存関係が追加されています。この悪意のあるパッケージには、開発者のマシンからビットコインを盗もうとする暗号化手法が含まれています。 これらの問題を解決するために、新しい

npm

バージョンでは 暗号化アルゴリズム を使用して、インストールされたパッケージの整合性をチェックします。 SHA-512

yarn

Yarn Classic

Yarn Berry は、最初から checksum を使用して、各パッケージの完全性。 Yarn は、package.json で宣言されていない悪意のあるパッケージを取得できないようにすることも試みます。不一致が見つかった場合、インストールは中止されます。 PnP モードの

Yarn Berry

には、従来の node_modules 方式のようなセキュリティの問題はありません。 Yarn Classic と比較して、Yarn Berry はコマンド実行のセキュリティが向上しています。 package.json で宣言されたパッケージのみを実行できます。このセキュリティ機能は、以下で説明する pnpm に似ています。

pnpm

pnpm

または チェックサムを使用して、コードを実行する前に、インストールされている各パッケージの整合性を検証します。 上で述べたように、

npm

Yarn Classic には、プロモーションによる セキュリティ問題があります。 pnpm は、管理モデルで昇格を使用せず、代わりにネストされた node_modules フォルダーを生成するため、この状況を回避し、不正な依存関係アクセスのリスクを排除します。これは、依存関係が .package.json で宣言されていることを意味します。 すでに説明したように、ブースト アルゴリズムは

非決定的

依存関係を引き起こす可能性があるため、これは monorepo 設定で特に重要です。

热门项目使用状況


##PrismaMeteorNext.jsRedux ToolkitSvelteKitApollo ServerGatsby##Nuxt

結論


確かに、さまざまなパッケージ マネージャーの原則には大きな違いがあります。

pnpm は、CLI の使用法が似ているため、最初は npm のように見えますが、依存関係の管理は大きく異なります。pnpm のアプローチパフォーマンスが向上し、ディスク容量効率が最適化されます。 Yarn Classic は依然として人気がありますが、レガシー ソフトウェアとみなされ、近い将来サポートが終了する可能性があります。 Yarn Berry PnP は真新しいものですが、パッケージ マネージャーの状況に再び革命を起こす可能性はまだ実現していません。

長年にわたり、多くのユーザーが 誰がどのパッケージ マネージャーを使用しているかについて尋ねてきましたが、全体として、Yarn Berry PnP の成熟度と導入に特に関心を持っているようです。

この記事の目的は、どのパッケージ マネージャーを使用するかを決定するための複数の視点を提供することです。特定のパッケージ マネージャーを推奨しているわけではないことを指摘しておきます。それはさまざまな要件をどのように比較検討するかによって異なります。したがって、好きなものを選択することができます。

英語の元のアドレス: https://blog.logrocket.com/javascript-package-managers-compared/

ノード関連の知識の詳細については、以下を参照してください。

nodejs チュートリアル!





npm Yarn Classic Yarn Berry pnpm
Svelte React Jest ( node_modules) Vue 3
Preact Angular ストーリーブック (node_modules付き) ブラウザリスト
Express.js Ember #Babel (node_modules を使用)
(node_modules 付き)






#React アプリの作成


webpack-cli
########################感情#########################

以上がJavaScript パッケージマネージャーの比較: Npm vs Yarn vs Pnpmの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はlogrocket.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。