Artikel ini akan membawa anda melalui tiga pengurus pakej JavaScript (npm, yarn, pnpm), membandingkan ketiga-tiga pengurus pakej ini dan bercakap tentang perbezaan dan perhubungan antara npm, yarn dan pnpm Saya harap Ia akan membantu semua orang. Jika anda mempunyai sebarang soalan, sila nyatakan!
Tiga pemain utama dalam ruang pengurus pakej:
Kami' telah melaksanakan fungsi yang pada asasnya serupa dalam semua pengurus pakej, jadi anda berkemungkinan besar akan memutuskan pengurus pakej mana yang hendak digunakan berdasarkan keperluan bukan fungsi, seperti kelajuan pemasangan, penggunaan storan atau kepraktisan.
Sudah tentu, cara anda memilih untuk menggunakan setiap pengurus pakej adalah berbeza, tetapi semuanya mempunyai konsep yang sama. Semua pengurus pakej di atas boleh melaksanakan arahan berikut:
Walau bagaimanapun, walaupun demikian, pengurus pakej adalah berbeza di bawah hud. Secara tradisinya npm
dan Yarn
mempunyai kebergantungan yang dipasang dalam folder node_modules berjubin. (Perhatikan pesanan di sini, yarn
dijubin dahulu, dan npm
sebelumnya adalah rekursif). Tetapi jubin juga boleh menyebabkan beberapa masalah keselamatan.
Oleh itu,
Ketidakpastianstruktur bergantung.
- Algoritma perataan itu sendiri adalah
kerumitan sangat tinggi dan mengambil masa yang lama.
- Anda masih boleh
akses haram dalam projek
- Pakej dengan kebergantungan yang diisytiharkan
memperkenalkan beberapa konsep baharu dalam folder pnpm
untuk menyimpan kebergantungan dengan lebih cekap. node_modules
malah pergi lebih jauh dengan meninggalkan mod Yarn Berry
(PnP) sepenuhnya (artikel lain akan menerangkan perkara ini secara terperinci). node_modules
, seawal Januari 2010. Ia mewujudkan prinsip teras cara pengurus pakej berfungsi hari ini. Tetapi memandangkan npm
telah wujud selama lebih 10 tahun, kenapa ada pilihan lain? Berikut ialah beberapa sebab utama mengapa ini berlaku: npm
node_modules
lwn. mod PnP) node_modules
hoisting
locking
) yarn
workspaces
kebolehselenggaraan dan kelajuan monorepos
Selepas Kebangkitan Sejarah bagaimana aspek ini ditentukan, bagaimana npm
menangani beberapa perkara ini isu, bagaimana Yarn Classic
mengembangkan konsep ini dan bagaimana pnpm
sebagai pengganti Yarn Berry
memecahkan konsep dan proses tradisional ini. Yarn Classic
ialah pencetus pengurus pakej. Ramai orang tersilap percaya bahawa npm
ialah akronim untuk "Pengurus pakej nod", tetapi npm
tidak demikian.
memperkenalkan perkara seperti fail dan medan metadatanya, menyimpan kebergantungan dalam npm
, skrip tersuai, pakej awam dan peribadi dan banyak lagi. node_modules
GitHub memperoleh npm, jadi pada dasarnya kini diuruskan oleh Microsoft. Pada masa penulisan, npm
versi utama terkini ialah v8, dikeluarkan pada Oktober 2021.
Pada Oktober 2016, Facebook mengumumkan perkongsian dengan Google dan beberapa syarikat lain untuk membangunkan pengurus pakej baharu (engineering.fb.com / 2016/10/11/…) untuk menangani isu konsistensi, keselamatan dan prestasi yang wujud dengan npm pada masa itu. Mereka menamakan penggantinya Benang.
Walaupun Yarn
masih diarkib dan direka bentuk berdasarkan banyak konsep dan proses npm
, Yarn
telah memberi impak yang ketara dalam bidang pengurus pakej. Berbanding dengan npm
, Yarn
menyelaraskan operasi untuk mempercepatkan proses pemasangan, yang telah menjadi titik kesakitan utama dengan versi npm
yang terdahulu.
Yarn
menetapkan standard yang lebih tinggi untuk membaca dan menulis, keselamatan dan prestasi serta mencipta banyak konsep (yang npm
kemudiannya membuat banyak penambahbaikan untuknya), termasuk:
monorepo
Menyokong Locking
)Yarn v1 Masuk mod penyelenggaraan pada tahun 2020. Sejak itu, siri v1.x telah dianggap warisan dan dinamakan semula Yarn Classic
. Penggantinya Yarn v2 (Berry) kini merupakan cawangan pembangunan yang lebih aktif.
pnpm
pnpm
dikeluarkan pada 2017 oleh Zoltan Kochan. Ia adalah pengganti untuk npm
, jadi jika anda mempunyai projek npm
, anda boleh menggunakan pnpm
dengan segera!
Sebab utama untuk mencipta pnpm
ialah npm
dan Yarn
sangat berlebihan untuk struktur storan pergantungan yang digunakan merentas projek. Walaupun Yarn Classic
mempunyai kelebihan kelajuan berbanding npm
, ia menggunakan kaedah resolusi pergantungan yang sama, yang tidak mungkin untuk pnpm
: npm
dan Yarn Classic
menggunakan hoisting
untuk menjubinkan node_modules
mereka.
pnpm
Daripada mengoptimumkan struktur sebelumnya, strategi penyelesaian pergantungan lain diperkenalkan: Struktur storan beralamat kandungan. Folder node_modules
yang dihasilkan oleh kaedah ini sebenarnya bergantung pada direktori ~/.pnpm-store/
yang disimpan secara global pada folder utama. Setiap versi kebergantungan disimpan secara fizikal sekali dalam folder direktori ini, membentuk satu alamat sumber untuk menjimatkan ruang cakera yang besar. Struktur
node_modules
dicipta dengan menggunakan symlinks
untuk mencipta struktur kebergantungan bersarang (di mana setiap fail/pakej dalam folder disimpan melalui pautan keras) daripada rasmi dokumentasi Imej di bawah menggambarkan perkara ini. (Untuk diisi: pautan lembut dan keras)
Pengaruh boleh dilihat dalam laporan 2021 pnpm
: kerana mereka boleh Untuk inovasi dalam storan boleh alamat , pesaing sedang mencari untuk menerima pakai konsep seperti pnpm
struktur pautan simbolik dan pengurusan cakera yang cekap bagi pakej.
Benang 2 Dikeluarkan pada Januari 2020, dinaikkan pangkat sebagai asal Peningkatan besar . Yarn
Pasukan memanggilnya Yarn
untuk menjadikannya lebih jelas bahawa pada dasarnya ia adalah pengurus pakej baharu dengan asas kod baharu dan prinsip baharu. Yarn Berry
Inovasi utama
Yarn Berry
ialah pendekatan Plug and Play (PnP) , yang berfungsi sebagai strategi untuk membaiki modul_nod. Daripada strategi menjana node_modules
, jana fail .pnp.cjs
dengan jadual carian kebergantungan, yang mengendalikan kebergantungan dengan lebih cekap kerana ia merupakan satu fail dan bukannya struktur folder bersarang. Selain itu, setiap pakej disimpan dalam folder sebagai fail zip dan bukannya .yarn/cache/
dan menggunakan ruang cakera kurang daripada node_modules
.
Semua perubahan ini berlaku dengan pantas sehingga menimbulkan banyak kontroversi selepas dikeluarkan. Memecah pecah perubahan seperti ini kepada PnP memerlukan penyelenggara mengemas kini pakej sedia ada mereka agar serasi dengannya. Menggunakan pendekatan PnP baharu secara lalai dan kembali kepada node_modules
pada mulanya tidak mudah, yang menyebabkan ramai pembangun berprofil tinggi tidak mempertimbangkan untuk menyertai dan secara terbuka mengkritik Yarn 2 .
Sejak itu, pasukan Yarn Berry
telah menyelesaikan banyak isu dalam keluaran berikutnya. Untuk menyelesaikan isu ketidakserasian PnP, pasukan telah menyediakan cara untuk menukar mod pengendalian lalai dengan mudah. Dengan bantuan pemalam node_modules , beralih kembali kepada pendekatan node_modules
tradisional hanya memerlukan satu baris konfigurasi.
Selain itu, ekosistem JavaScript telah memberikan lebih banyak sokongan untuk PnP dari semasa ke semasa, dan seperti yang anda boleh lihat dalam jadual keserasian ini beberapa besar Projek telah mula menerima pakai Yarn Berry
.
Walaupun Yarn Berry
masih muda, ia sudah memberi kesan kepada ruang pengurus pakej - pnpm
menerima pakai pendekatan PnP pada akhir 2020.
Pengurus pakej mesti dipasang terlebih dahulu pada setiap sistem tempatan dan CI/CD pembangun.
npm
disertakan dengan Node.js
jadi tiada langkah tambahan diperlukan. Selain memuat turun Pemasang Node.js untuk sistem pengendalian anda, sudah menjadi amalan biasa untuk menggunakan alatan CLI untuk mengurus versi perisian. Dalam konteks Node, Pengurus Versi Node (nvm) atau Volta telah menjadi utiliti yang sangat berguna.
Anda boleh memasang Yarn 1 dengan cara yang berbeza, contohnya, sebagai pakej npm
:.$ npm i -g yarn
Untuk berhijrah daripada Yarn Classic kepada Yarn Berry, kaedah yang disyorkan ialah:
Pasang atau kemas kini Yarn Classic
kepada versi terkini
Naik taraf kepada versi moden terkini menggunakan arahan
yarn set version berry
Walau bagaimanapun, berikut ialah pemasangan Yarn Berry yang disyorkan Kaedahnya melalui Corepack.
Corepack是由 Yarn Berry 的开发者创建的。该计划最初被命名为包管理器管理器(pmm) ?,并在 LTS v16 中与 Node 合并。
在 Corepack 的帮助下,因为 Node 包含 Yarn Classic
、Yarn Berry
和 pnpm
二进制文件所以您不必“单独”安装的 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
作为 npm
包来安装: $ npm i -g pnpm
。您还可以使用 Corepack 安装 pnpm :
$ corepack prepare pnpm@6.24.2 --activate
在本节中,您将一目了然地看到不同包管理器的主要特征。您可以轻松发现配置特定包管理器涉及哪些文件,以及哪些文件是由安装步骤生成的。
所有包管理器都将所有重要的元信息存储在项目清单package.json文件中。 此外,根级别的配置文件可以被用来设置不同的私有包或者不同的依赖项解析配置。
在安装步骤中,依赖项 dependencies
被存储在文件结构中,例如 node_modules
并生成锁定文件 locking
。本节不考虑工作区设置,因此所有示例仅显示存储依赖项的单个位置。
使用$ npm install
或较短的 $ npm i
会生成一个 package-lock.json
文件和一个 node_modules
文件夹。还有 .npmrc
这种可配置的文件可以放在根级别目录里面。有关 locking
文件的更多信息,请参阅下一节。
. ├── node_modules/ ├── .npmrc ├── package-lock.json └── package.json
运行 $ 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
项目中处理更多的文件和文件夹。有些是可选的,有些是强制性的。
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
无论是对于PnP 的严格模式还是松散模式,跟着 .pnp.cjs
和 yarn.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`
和 npm
或 Yarn 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
文件夹结构中。这是 npm
、Yarn Classic 和 pnpm都使用的方案,(其中 pnpm
比其他方案更有效)。
Yarn Berry
在 PnP 模式下的做法有所不同。依赖项不是 node_modules
文件夹,而是以 zip 文件的形式存储为 .yarn/cache/
和 .pnp.cjs
文件的组合。
最好将这些锁定文件置于版本控制之下,因为每个团队成员都安装相同的版本,所以它解决了“在你和我的机器上工作”问题。
下表比较了 npm
、Yarn Classic
、Yarn Berry
和 pnpm
中可用的不同 CLI 命令。这绝不是一个完整的列表,而是一个备忘单。本节不涉及与workflow 相关的命令。
npm
和 pnpm
具有许多特别的命令和选项别名,这意味着命令可以有不同的名称,即$ npm install
与 $ npm add
。 此外,许多命令选项都有缩写版本,例如 -D
来代替 --save-dev
。
在表格中,我将所有缩写版本称为别名。使用这些包管理器,您都可以增加、更新或删除多个依赖项。
此表涵盖了用于安装或更新 package.json
中指定的所有依赖项的依赖项管理命令。
Action | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
install deps in package.json | npm install alias: i, add | yarn install or yarn | like Classic | pnpm install alias: i |
update deps in package.json acc. semver | npm update alias: up, upgrade | yarn upgrade | yarn semver up (via plugin) | pnpm update alias: up |
update deps in package.json to latest | N/A | yarn upgrade --latest | yarn up | pnpm update --latest alias: -L |
update deps acc. semver | npm update react | yarn upgrade react | yarn semver up react | pnpm up react |
update deps to latest | npm update react@latest | yarn upgrade react --latest | yarn up react | pnpm up -L react |
update deps interactively | N/A | yarn upgrade-interactive | yarn upgrade-interactive (via plugin) | $ pnpm up --interactive alias: -i |
add runtime deps | npm i react | yarn add react | like Classic | pnpm add react |
add dev deps | npm i -D babel alias: --save-dev | yarn add -D babel alias: --dev | like Classic | pnpm add -D babel alias: --save-dev |
add deps to package.json without semver | npm i -E react alias: --save-exact | yarn add -E react alias: --exact | like Classic | pnpm add -E react alias: --save-exact |
uninstall deps and remove from package.json | npm uninstall react alias: remove, rm, r, un, unlink | yarn remove react | like Classic | pnpm remove react alias: rm, un, uninstall |
uninstall deps w/o update of package.json | npm uninstall --no-save | N/A | N/A | N/A |
Contoh berikut menunjukkan cara mengurus pakej semasa pembangunan. Istilah yang digunakan dalam jadual:
- Pakej: kebergantungan atau binari
- Perduaan: Alat pelaksanaan daripada
node_modules/.bin/
atau.yarn/cache/
(PnP)
Adalah penting untuk memahami bahawa Yarn Berry
hanya membenarkan kami melaksanakan binari tertentu yang berada di dalam package.json
atau terdedah dalam fail bin/
.
Action | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
install packages globally | npm i -g ntl alias: --global | yarn global add ntl | N/A (global removed) | pnpm add --global ntl |
update packages globally | npm update -g ntl | yarn global upgrade ntl | N/A | pnpm update --global ntl |
remove packages globally | npm uninstall -g ntl | yarn global remove ntl | N/A | pnpm remove --global ntl |
run binaries from terminal | npm exec ntl | yarn ntl | yarn ntl | pnpm ntl |
run binaries from script | ntl | ntl | ntl | ntl |
dynamic package execution | npx ntl | N/A | yarn dlx ntl | pnpm dlx ntl |
add runtime deps | npm i react | yarn add react | like Classic | pnpm add react |
add dev deps | npm i -D babel alias: --save-dev | yarn add -D babel alias: --dev | like Classic | pnpm add -D babel alias: --save-dev |
add deps to package.json without semver | npm i -E react alias: --save-exact | yarn add -E react alias: --exact | like Classic | pnpm add -E react alias: --save-exact |
uninstall deps and remove from package.json | npm uninstall react alias: remove, rm, r, un, unlink | yarn remove react | like Classic | pnpm remove react alias: rm, un, uninstall |
uninstall deps w/o update of package.json | npm uninstall --no-save | N/A | N/A | N/A |
Jadual ini merangkumi beberapa arahan terbina dalam yang berguna. Jika tiada arahan rasmi, arahan pihak ketiga biasanya boleh digunakan melalui pakej npm
atau pemalam Yarn Berry
.
Action | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
发包 | npm publish | yarn publish | yarn npm publish | pnpm publish |
list installed deps | npm ls alias: list, la, ll | yarn list | pnpm list alias: ls | |
list outdated deps | npm outdated | yarn outdated | yarn upgrade-interactive | pnpm outdated |
print info about deps | npm explain ntl alias: why | yarn why ntl | like Classic | pnpm why ntl |
init project | npm init -y npm init (interactive) alias: --yes | yarn init -y yarn init (interactive) alias: --yes | yarn init | pnpm init -y pnpm init (interactive) alias: --yes |
print licenses info | N/A (via third-party package) | yarn licenses list | N/A (or via plugin, other plugin) | N/A (via third-party package) |
update package manager version | N/A (with third-party tools, e.g., nvm) | with npm: yarn policies set-version 1.13.0 | with Corepack: yarn set version 3.1.1 | N/A (with npm, Corepack) |
perform security audit | npm audit | yarn audit | yarn npm audit | pnpm audit |
add deps to package.json without semver | npm i -E react alias: --save-exact | yarn add -E react alias: --exact | like Classic | pnpm add -E react alias: --save-exact |
uninstall deps and remove from package.json | npm uninstall react alias: remove, rm, r, un, unlink | yarn remove react | like Classic | pnpm remove react alias: rm, un, uninstall |
uninstall deps w/o update of package.json | npm uninstall --no-save | N/A | N/A | N/A |
配置包管理器发生在您的 package.json
和专用的配置文件中。
monorepo
中的工作区大多数配置发生在专用配置文件 .npmrc
中。
如果你想使用 npm
的 workspaces
功能,你必须在 package.json
中添加workspaces 元数据字段来告诉 npm 在哪里可以找到子项目或工作空间的文件夹。
// ... "workspaces": [ "hooks", "utils" ] }
每个包管理器都可以使用公共 npm
注册表。或许你很可能希望重用它们而不将它们发布到公共注册表。您可以在 .npmrc
文件中执行此操作配置来私有注册表。( 现在基本都有私有源了)
# .npmrc @doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/
npm
存在许多配置选项,最好在文档中查看它们。\
您可以在 package.json
中设置 yarn
的 workspaces
(必须是私有包)。
{ // ... "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
中配置 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
使用与 npm
相同的配置机制,因此您可以使用 .npmrc
文件。配置私有注册表的工作方式也与使用 npm
相同。借助 pnpm 的工作空间功能可以支持多包项目。要初始化 monorepo
,您必须在 pnpm-workspace.yaml
文件中指定包的位置。
# pnpm-workspace.yaml packages: - 'packages/**'
(这里其实就是三种概念,单仓库多项目,单仓库单项目,多仓库多项目)
monorepo
是一个包含多个项目的存储库,这些项目被称为 workspace
或者包。将所有内容保存在一个地方而不是使用多个存储库是一种项目组织策略。
当然,这会带来额外的复杂性。Yarn Classic
是第一个启用此功能的,但现在每个主要的包管理器都提供了工作区功能。本节展示如何使用每个不同的包管理器配置工作区。
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 目前不支持高级过滤或并行执行多个与工作区相关的命令。
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 Classic
的概念之上的。在Reddit 评论中,Yarn Berry 的主要开发人员简要概述了面向工作空间的功能,包括:
Yarn Berry
使用大量可用于 package.json
文件的 dependencies
或 devDependencies
字段的协议。其中就有 workspace
协议。
与 Yarn Classic
的工作区相比,Yarn Berry
明确定义依赖项必须是此 monorepo
中的包之一。否则如果版本不匹配,Yarn Berry
可能会尝试从远程注册表获取其版本。
{ // ... "dependencies": { "@doppelmutzi/hooks": "workspace:*", "http-server": "14.0.0", // ... } }
通过 workspace
这种协议,pnpm
促成了类似于 Yarn Berry
的 monorepo
项目。许多 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/`
性能是选型决策的关键部分。本节展示了基于一个小型和一个中型项目的基准测试。以下是有关示例项目的一些说明:
我用三个用例 (UC) 对我们的每个包管理器变体进行了一次测量。要了解详细的评估和解释,请查看项目 1 (P1)和项目 2 (P2)的结果。
node_modules
或 .pnp.cjs
node_modules
或 .pnp.cjs
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
Agak terlalu pemaaf apabila berurusan dengan pakej yang buruk dan menghadapi beberapa Kerentanan keselamatan yang memberi kesan secara langsung kepada banyak projek. Contohnya, dalam versi 5.7.0, apabila anda melaksanakan perintah sudo npm
pada sistem pengendalian Linux, anda boleh menukar pemilikan fail sistem, menjadikan sistem pengendalian tidak dapat digunakan.
Satu lagi insiden berlaku pada 2018 melibatkan kecurian Bitcoin. Pakej Node.js EventStream menambah kebergantungan berniat jahat dalam versi 3.3.6nya. Pakej berniat jahat ini mengandungi kaedah kriptografi yang cuba mencuri Bitcoin daripada mesin pembangun.
Untuk membantu menyelesaikan isu ini, versi npm
baharu menggunakan algoritma kriptografi untuk menyemak integriti pakej anda yang dipasang. SHA-512.
Yarn Classic
dan Yarn Berry
gunakan checksum dari awal untuk mengesahkan integriti setiap pakej. Yarn
juga cuba menghalang anda daripada mendapatkan semula pakej berniat jahat yang tidak diisytiharkan dalam package.json
: jika ketidakpadanan ditemui, pemasangan akan dibatalkan.
Mod PnP Yarn Berry
tidak mempunyai isu keselamatan kaedah node_modules
tradisional. Berbanding dengan Yarn Classic
, Yarn Berry
meningkatkan keselamatan pelaksanaan arahan. Anda hanya boleh melaksanakan pakej yang telah diisytiharkan dalam package.json
. Ciri keselamatan ini serupa dengan pnpm
, yang akan saya terangkan di bawah.
pnpm
atau menggunakan jumlah semak untuk mengesahkan integriti setiap pakej yang dipasang sebelum melaksanakan kodnya.
Seperti yang kami nyatakan di atas, kedua-dua npm
dan Yarn Classic
mengalami isu keselamatan akibat kenaikan pangkat. pnpm
mengelakkan situasi ini kerana model pengurusannya tidak menggunakan pengangkat sebaliknya, ia menghasilkan folder node_modules
bersarang, sekali gus menghapuskan risiko akses bergantung yang menyalahi undang-undang. Ini bermakna kebergantungan diisytiharkan dalam .package.json
.
Seperti yang kita bincangkan, ini amat penting dalam tetapan monorepo
, memandangkan peningkatan algoritma kadangkala boleh membawa kepada bukan penentu yang bergantung kepada .
npm | Yarn Classic | Yarn Berry | pnpm |
Svelte | React | Jest (with node_modules) | Vue 3 |
Preact | Angular | Storybook (with node_modules) | Browserlist |
Express.js | Ember | Babel (with node_modules) | Prisma |
Meteor | Next.js | Redux Toolkit (with node_modules) | SvelteKit |
Apollo Server | Gatsby | ||
Nuxt | |||
Create React App | |||
webpack-cli | |||
Emotion |
Memang terdapat perbezaan besar dalam prinsip pengurus pakej yang berbeza.
pnpm
pada mulanya kelihatan seperti npm
kerana penggunaan CLI mereka adalah serupa tetapi pendekatan pengurusan kebergantungan adalah sangat berbeza; pnpm
Masih popular, tetapi ia dianggap perisian warisan dan sokongan mungkin akan digugurkan dalam masa terdekat. Yarn Classic
adalah serba baharu, tetapi potensinya untuk merevolusikan landskap pengurus pakej sekali lagi masih belum direalisasikan. Yarn Berry PnP
siapa yang menggunakan pengurus pakej yang mana, dan secara keseluruhan orang nampaknya sangat berminat dengan kematangan dan penerimaan . Yarn Berry PnP
Alamat asal bahasa Inggeris: https://blog.logrocket.com/javascript-package-managers-compared/Untuk lebih banyak pengetahuan berkaitan nod, sila lawati:
tutorial nodejs!
Atas ialah kandungan terperinci Pengurus pakej JavaScript dibandingkan: Npm vs Yarn vs Pnpm. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!