Es gibt drei Hauptakteure im Bereich der Paketmanager:
npm
Yarn
High-Performance npm (pnpm)
Wir haben grundsätzlich ähnliche Funktionen in allen Paketmanagern implementiert, sodass Sie sich höchstwahrscheinlich auf der Grundlage nichtfunktionaler Paketmanager entscheiden werden, welche Sie verwenden möchten B. Installationsgeschwindigkeit, Speicherverbrauch oder Praktikabilität.
Natürlich ist die Art und Weise, wie Sie die einzelnen Paketmanager verwenden, unterschiedlich, aber im Grunde haben sie alle einheitliche Konzepte. Alle oben genannten Paketmanager können die folgenden Befehle ausführen:
. Dennoch sind Paketmanager unter der Haube unterschiedlich. Traditionell installierten npm
und Yarn
Abhängigkeiten in einem flachen Ordner „node_modules“. (Achten Sie hier auf die Reihenfolge, yarn
wird zuerst gekachelt und npm
war zuvor rekursiv). Aber Fliesen können auch eine Reihe von Sicherheitsproblemen mit sich bringen.
Unsicherheit der Abhängigkeitsstruktur.
Der Flattening-Algorithmus selbst ist sehr komplex und zeitaufwändig.
Auf Pakete mit deklarierten Abhängigkeiten
kann im Projekt weiterhin illegal zugegriffen werden.
Daher hat pnpm
einige neue Konzepte im Ordner node_modules
eingeführt, um Abhängigkeiten effizienter zu speichern. Yarn Berry
geht sogar noch einen Schritt weiter, indem es den (PnP-)Modus von node_modules
vollständig aufgibt (mehr dazu in einem anderen Artikel).
Der früheste veröffentlichte Paketmanager war npm
im Januar 2010. Es legte die Grundprinzipien der heutigen Arbeitsweise von Paketmanagern fest. Aber warum gibt es keine andere Option, da es npm
schon seit über 10 Jahren gibt? Hier sind einige Hauptgründe, warum dies der Fall sein könnte:
node_modules
verfügt über unterschiedliche Algorithmen zur Abhängigkeitsauflösung (verschachtelt und gekachelt, node_modules
vs. PnP-Modus) undhoisting
).locking
(unterschiedliche Leistung, z. B. das von yarn
selbst geschriebene)workspaces
), was sich auf die Wartbarkeit und Geschwindigkeit von monorepos
auswirkt.Lassen Sie uns näher darauf eingehen die Geschichte, wie diese Aspekte nach dem Aufstieg von npm
bestimmt wurden, wie Yarn Classic
einige dieser Probleme löste, wie pnpm
diese Konzepte erweiterte und wie Yarn Berry
als Nachfolger von Yarn Classic
diese traditionellen Konzepte und Prozesse durchbricht.
npm
ist der Erfinder von Paketmanagern. Viele Leute glauben fälschlicherweise, dass npm
ein Akronym für „Node Package Manager“ ist, aber das ist nicht der Fall.
Die Veröffentlichung stellte eine Revolution dar, da zuvor Projektabhängigkeiten manuell heruntergeladen und verwaltet wurden. npm
führte Dinge wie Dateien und ihre Metadatenfelder, das Speichern von Abhängigkeiten in node_modules
, benutzerdefinierte Skripte, öffentliche und private Pakete und mehr ein.
Im Jahr 2020 erwarb GitHub npm, sodass npm
im Prinzip nun von Microsoft verwaltet wird. Zum Zeitpunkt des Verfassens dieses Artikels ist die neueste Hauptversion Version 8, die im Oktober 2021 veröffentlicht wurde.
Im Oktober 2016 kündigte Facebook eine Partnerschaft mit Google und einer Reihe anderer Unternehmen an, um einen neuen Paketmanager zu entwickeln (engineering.fb.com/2016/10/11/…), um die damals bestehende Konsistenz von npm zu beheben. Sicherheits- und Leistungsprobleme. Sie nannten das Ersatzgarn.
Obwohl die Architektur und das Design von Yarn
immer noch auf vielen Konzepten und Prozessen von npm
basieren, hatte Yarn
einen erheblichen Einfluss auf den Bereich der Paketmanager. Im Vergleich zu npm
parallelisiert Yarn
Vorgänge, um den Installationsprozess zu beschleunigen, was bei früheren Versionen von npm
ein großes Problem darstellte.
Yarn
setzte höhere Standards für Lesen und Schreiben, Sicherheit und Leistung und erfand viele Konzepte (später hat npm
auch viele Verbesserungen dafür vorgenommen), darunter:
monorepo
unterstütztLocking
)Yarn v1 in Eintritt in den Wartungsmodus in 2020. Seitdem gilt die v1.x-Serie als Legacy und wurde in Yarn Classic
umbenannt. Sein Nachfolger Yarn v2 (Berry) ist nun der aktivere Entwicklungszweig.
pnpm
Version 1 von pnpm
wurde 2017 von Zoltan Kochan veröffentlicht. Es ist ein Ersatz für npm
. Wenn Sie also ein npm
-Projekt haben, können Sie pnpm
sofort verwenden!
Der Hauptgrund für die Erstellung pnpm
besteht darin, dass npm
und Yarn
im Hinblick auf die projektübergreifenden Abhängigkeitsspeicherstrukturen sehr redundant sind. Obwohl Yarn Classic
einen Geschwindigkeitsvorteil gegenüber npm
hat, verwendet es dieselbe Methode zur Abhängigkeitsauflösung wie pnpm
: npm
und Yarn Classic
verwenden hoisting
um ihre node_modules
zu reduzieren.
pnpm
die vorherige Struktur zu optimieren, wird eine andere Strategie zur Abhängigkeitsauflösung vorgeschlagen: a Inhaltsadressierte Speicherstruktur. Der durch diese Methode generierte Ordner node_modules
basiert tatsächlich auf dem Verzeichnis ~/.pnpm-store/
das global im Hauptordner gespeichert ist. Jede Version von Abhängigkeiten wird physisch einmal in diesem Verzeichnisordner gespeichert und bildet so eine einzige Quelladresse, um erheblich Speicherplatz zu sparen.
Die node_modules
-Struktur ist eine verschachtelte Struktur von Abhängigkeiten, die mithilfe von symlinks
erstellt werden (wobei jede Datei/jedes Paket in einem Ordner über einen festen Link gespeichert wird). Die folgende Abbildung aus der offiziellen Dokumentation veranschaulicht dies. (Zu füllende Bilder: Soft- und Hardlinks)
Der Einfluss von pnpm
wird im Bericht 2021 deutlich: Aufgrund ihrer Innovationen im inhaltsadressierbaren Speicher versuchen Wettbewerber, pnpm
-Konzepte zu übernehmen, etwa die Struktur symbolischer Links und die effiziente Festplattenverwaltung von Paketen.
wurde im Januar 2020 veröffentlicht und als wesentliches Upgrade des ursprünglichen Yarn
in Rechnung gestellt. Das Yarn
-Team nennt es Yarn Berry
um deutlicher zu machen, dass es sich im Wesentlichen um einen neuen Paketmanager mit einer neuen Codebasis und neuen Prinzipien handelt.
Die Hauptinnovation von Yarn Berry
ist sein Plug-and-Play-Ansatz (PnP) als Strategie zur Reparatur von Knotenmodulen. Anstelle der Strategie, node_modules
zu generieren, generieren Sie eine Datei .pnp.cjs
mit einer Abhängigkeits-Nachschlagetabelle, die eine effizientere Handhabung von Abhängigkeiten ermöglicht, da es sich um eine einzelne Datei und nicht um eine verschachtelte Ordnerstruktur handelt. Darüber hinaus wird jedes Paket in einem Ordner in Form einer ZIP-Datei anstelle von .yarn/cache/
gespeichert und benötigt weniger Speicherplatz als node_modules
.
Alle diese Änderungen erfolgten so schnell, dass sie nach ihrer Veröffentlichung große Kontroversen auslösten. Solche bahnbrechenden Änderungen an PnP erfordern von den Betreuern, dass sie ihre vorhandenen Pakete aktualisieren, um damit kompatibel zu sein. Die standardmäßige Verwendung des neuen PnP-Ansatzes und die Rückkehr zu node_modules
war zunächst nicht einfach, was dazu führte, dass viele bekannte Entwickler dies nicht in Betracht zogen und Yarn 2 öffentlich kritisierten.
Seitdem hat das Yarn Berry
-Team in seinen nachfolgenden Veröffentlichungen viele Probleme behoben. Um PnP-Inkompatibilitätsprobleme zu beheben, hat das Team eine Möglichkeit bereitgestellt, den Standardbetriebsmodus einfach zu ändern. Mit Hilfe des Node_modules-Plugins ist für die Rückkehr zum traditionellen node_modules
-Ansatz nur eine Konfigurationszeile erforderlich.
Darüber hinaus hat das JavaScript-Ökosystem im Laufe der Zeit zunehmend Unterstützung für PnP bereitgestellt, und wie Sie in dieser Kompatibilitätstabelle sehen können, haben einige große Projekte mit der Einführung Yarn Berry
begonnen.
Auch wenn Yarn Berry
noch jung ist, hat es bereits Auswirkungen auf den Bereich der Paketmanager – pnpm
hat den PnP-Ansatz Ende 2020 übernommen.
Der Paketmanager muss zunächst auf den lokalen und CI/CD-Systemen jedes Entwicklers installiert werden.
npm
wird mit Node.js
ausgeliefert, sodass keine zusätzlichen Schritte erforderlich sind. Neben dem Herunterladen des Node.js-Installationsprogramms für Ihr Betriebssystem ist es mittlerweile gängige Praxis, CLI-Tools zum Verwalten von Softwareversionen zu verwenden. Im Zusammenhang mit Node hat sich Node Version Manager (nvm) oder Volta zu einem sehr praktischen Dienstprogramm entwickelt.
Sie können Yarn 1 auf unterschiedliche Weise installieren, zum Beispiel als npm
-Paket: .$ npm i -g yarn
Um von Yarn Classic zu Yarn Berry zu migrieren, ist die empfohlene Methode:
Installieren oder aktualisieren Sie Yarn Classic
auf
Version
verwenden Sie den Befehl „
Garn Set Version Berry“.
Die empfohlene Methode zur Installation von Yarn Berry ist jedoch Corepack.
Corepack wurde von den Entwicklern von Yarn Berry erstellt. Die Initiative hieß ursprünglich Package Manager Manager (pmm) und wurde in LTS v16 mit Node zusammengeführt.
Mithilfe von Corepack ist Node ein alternativer Paketmanager zu npm
, den Sie nicht „separat“ installieren müssen, da er die Binärdateien Yarn Classic
, Yarn Berry
und pnpm
enthält. Mit diesen Shims können Benutzer Yarn- und PNPM-Befehle ausführen, ohne sie zuerst explizit zu installieren und ohne die Node-Verteilung durcheinander zu bringen.
Corepack ist mit Node.js ≥ v16.9.0 vorinstalliert. Bei älteren Node-Versionen können Sie jedoch ⬇️
npm install -g corepackverwenden
, um Corepack zu aktivieren, bevor Sie es verwenden. Dieses Beispiel zeigt, wie man es in Yarn Berry v3.1.1 aktiviert.
# Sie müssen sich zuerst anmelden $ corepack aktivieren # Shim installiert, aber konkrete Version muss aktiviert werden $ corepack Prepare [email protected] --activate
Sie können pnpm
als npm
-Paket installieren: $ npm i -g pnpm
. Sie können pnpm auch mit Corepack installieren:
$ corepack Prepare [email protected] --activate
In diesem Abschnitt sehen Sie auf einen Blick die Hauptfunktionen verschiedener Paketmanager. Sie können leicht herausfinden, welche Dateien an der Konfiguration eines bestimmten Paketmanagers beteiligt sind und welche Dateien durch den Installationsschritt generiert werden.
Alle Paketmanager speichern alle wichtigen Metainformationen in der Projektmanifestdatei package.json. Darüber hinaus können Konfigurationsdateien auf Root-Ebene verwendet werden, um verschiedene private Pakete oder verschiedene Konfigurationen für die Abhängigkeitsauflösung einzurichten.
Während des Installationsschritts werden dependencies
in einer Dateistruktur wie node_modules
gespeichert und eine locking
generiert. In diesem Abschnitt werden Arbeitsbereichseinstellungen nicht berücksichtigt, daher zeigen alle Beispiele nur einen einzigen Speicherort, an dem Abhängigkeiten gespeichert werden.
mit $ npm install
oder dem kürzeren $ npm i
eine package-lock.json
Datei und einen node_modules
-Ordner. Es gibt auch konfigurierbare Dateien wie .npmrc
, die im Stammverzeichnis abgelegt werden können. Weitere Informationen zum locking
Dateien finden Sie im nächsten Abschnitt.
. ├── node_modules/ ├── .npmrc ├── package-lock.json └── package.json
das $ yarn
ausführt, erstellt eine yarn.lock
Datei und einen node_modules
-Ordner. .yarnrc
Dateien können auch Konfigurationsoptionen sein, und Yarn Classic
unterstützt auch .npmrc
Dateien. Alternativ können Sie den Cache-Ordner .yarn/cache/
und die neueste Yarn Classic
Version verwenden, die lokal in .yarn/releases/
gespeichert ist.
. ├── .garn/ │ ├── Cache/ │ └── Veröffentlichungen/ │ └── Garn-1.22.17.cjs ├── node_modules/ ├── .yarnrc ├── package.json └── Yarn.lock
Aufgrund dieses speziellen Installationsmodus müssen Sie in Ihrem Yarn Berry
-Projekt mit mehr Dateien und Ordnern umgehen als bei anderen Paketmanagern. Einige sind optional und andere obligatorisch.
Yarn Berry
unterstützt nicht mehr .npmrc
oder .yarnrc
; es erfordert eine .yarnrc.yml. Für den herkömmlichen Arbeitsablauf zum Generieren von node_modules
Ordnern müssen Sie nodeLinker
Konfiguration bereitstellen, um node_modules
oder pnpm
-Konfiguration verwenden zu können (diesen Teil verstehe ich nicht).
# .yarnrc.yml nodeLinker: node-modules # oder pnpm
mit $ yarn
installiert alle Abhängigkeiten in einem node_modules
-Ordner. Und es wird eine Datei yarn.lock
generiert, die zwar neuer, aber nicht mit Yarn Classic
kompatibel ist. Darüber hinaus wird ein .yarn/cache/
-Ordner für die Offline-Installation generiert. Dieser Ordner ist optional und wird zum Speichern der vom Projekt verwendeten Version von Yarn Berry
verwendet.
. ├── .garn/ │ ├── Cache/ │ └── Veröffentlichungen/ │ └── Garn-3.1.1.cjs ├── node_modules/ ├── .yarnrc.yml ├── package.json └── Yarn.lock
Unabhängig davon, ob es sich um einen strikten Modus oder einen losen Modus für PnP handelt, wird durch die Ausführung von $ yarn
mit .pnp.cjs
und yarn.lock
ein .yarn/cache/
und .yarn/unplugged
generiert. PnP strict ist der Standardmodus. Wenn Sie den Loose-Modus konfigurieren möchten, müssen Sie ihn in der folgenden Form aktivieren:
# .yarnrc.yml nodeLinker: pnp pnpMode: lose
In einem PnP-Projekt enthält der .yarn
Ordner neben dem releases
Ordner wahrscheinlich auch einen sdk/
-Ordner, der IDE-Unterstützung bietet. Abhängig von Ihrem Anwendungsfall kann .yarn
sogar mehr Ordner enthalten.
. ├── .garn/ │ ├── Cache/ │ ├── Veröffentlichungen/ │ │ └── Garn-3.1.1.cjs │ ├── sdk/ │ └── ausgesteckt/ ├── .pnp.cjs ├── .pnp.loader.mjs ├── .yarnrc.yml ├── package.json └── Yarn.lock`Der Anfangszustand von
ist der gleiche wie bei npm
oder Yarn Classic
, für package.json
pnpm
ist. Nach der Installation von Abhängigkeiten mit $ pnpm i
entsteht ein Ordner node_modules
, dessen Struktur jedoch völlig anders ist, da es sich bei seinem Inhalt um adressierbaren Speicher handelt.
pnpm
generiert außerdem eine eigene Sperrdatei pnp-lock.yml
. Mithilfe der optionalen .npmrc
Datei können Sie zusätzliche Konfigurationen bereitstellen.
. ├── node_modules/ │ └── .pnpm/ ├── .npmrc ├── package.json └── pnpm-lock.yml
Wie im vorherigen Abschnitt erwähnt, erstellt jeder Paketmanager Sperrdateien.
Die lock
speichert die genaue Version jeder von Ihrem Projekt installierten Abhängigkeit und ermöglicht so eine vorhersehbarere und deterministischere Installation. Diese lock
ist wichtig, da abhängige Versionen wahrscheinlich mit einem Versionsbereich (z. B. ≥ v1.2.5) deklariert werden und wenn Sie Ihre Version nicht „sperren“, kann die tatsächlich installierte Version anders sein.
Sperrdateien speichern manchmal auch Prüfsummen (einen Hash, soweit ich mich erinnere), worauf wir im Abschnitt „Sicherheit“ ausführlicher eingehen.
Ab npm
v5+ war das Sperren von Dateien immer die Hauptfunktion von npm
( package-lock.json
), in pnpm
Yarn Berry
erscheint pnpm-lock.yaml
yarn.lock
neuen YAML-Format.
Im vorherigen Abschnitt haben wir den traditionellen Ansatz gesehen, Abhängigkeiten in der Ordnerstruktur node_modules
zu installieren. Dies ist die von npm
, Yarn Classic und pnpm verwendete Lösung ( pnpm
ist effizienter als die anderen).
Yarn Berry
macht die Dinge im PnP-Modus anders. Anstelle des Ordners node_modules
werden Abhängigkeiten in ZIP-Dateien als Kombination aus .yarn/cache/
und .pnp.cjs
Dateien gespeichert.
Es ist besser, diese Sperrdateien unter Versionskontrolle zu stellen, da jedes Teammitglied dieselbe Version installiert, sodass das Problem „Funktioniert auf Ihrem und meinem Computer“ gelöst wird.
Die folgende Tabelle vergleicht die verschiedenen CLI-Befehle, die in npm
, Yarn Classic
, Yarn Berry
und pnpm
verfügbar sind. Dies ist keineswegs eine vollständige Liste, sondern eher ein Spickzettel. In diesem Abschnitt werden keine Workflow-bezogenen Befehle behandelt.
npm
und pnpm
haben viele Ad-hoc-Befehls- und Optionsaliase, was bedeutet, dass Befehle unterschiedliche Namen haben können, z. B. $ npm install
vs. $ npm add
. Darüber hinaus gibt es für viele Befehlsoptionen abgekürzte Versionen, z. B. -D
anstelle von --save-dev
. In der Tabelle nenne ich alle abgekürzten Versionen Aliase. Mit jedem dieser Paketmanager können Sie mehrere Abhängigkeiten hinzufügen, aktualisieren oder entfernen.
Diese Tabelle behandelt die Abhängigkeitsverwaltungsbefehle, die zum Installieren oder Aktualisieren aller in package.json
angegebenen Abhängigkeiten verwendet werden.
Aktion | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
install deps in package.json | npm install alias: i, | Yarn install hinzufügen oder Garn | wie Classic | pnpm install alias: i |
aktualisiere deps in package.json | npm update alias: up, upgrade | Yarn Upgrade | Yarn Semver Up (über Plugin) | pnpm Update Alias: up |
Update deps in package.json auf das neueste | N/A | Yarn Upgrade --latest | Yarn up | pnpm Update --latest Alias: |
-L | Update | Deps | Acc Semver Up React | PNPM Up React |
Update Deps auf das neueste | NPM-Update React@latest | Garn-Upgrade Reagieren --latest | Garn Up Reagieren | pnpm Up -L Reagieren |
Update Deps interaktiv | N/A | Garn-Upgrade-interaktiv | Garn-Upgrade-interaktiv (über Plugin) | $ pnpm up --interactive Alias: -i |
Runtime Deps | NPM hinzufügen 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 |
deps zu package.json ohne semver npm i hinzufügen | -E reagierender Alias: --save-exact | Yarn add -E reagierender Alias: --exact | wie klassisches | pnpm add -E reagierender Alias: - -save-exact |
deinstalliert Deps und entfernt aus package.json | npm | uninstall-React-Alias: Remove, RM, R, Un, | Unlink | Yarn |
. json | npm uninstall --no-save | N/A | N/A | N/A |
Das folgende Beispiel zeigt, wie Pakete während der Entwicklung verwaltet werden. In der Tabelle verwendete Begriffe:
- Paket: Abhängigkeit oder binär
- Binär: Ein Ausführungstool von
node_modules/.bin/
oder.yarn/cache/
(PnP)
Es ist wichtig zu verstehen, dass Yarn Berry
uns nur die Ausführung in package.json
oder Expose erlaubt die angegebenen Binärdateien in der bin/
-Datei.
Aktion | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
Pakete global installieren | npm i -g ntl Alias: --global | Yarn global add ntl | N/A (global entfernt) | pnpm add --global ntl |
Pakete global aktualisieren | npm update -g ntl | Yarn global upgrade ntl | N /A | pnpm update --global ntl |
Pakete global entfernen | npm uninstall -g ntl | Garn global ntl entfernen | N/A | pnpm entfernen --global ntl |
Binärdateien vom Terminal ausführen | npm exec ntl | Garn ntl | Garn ntl | pnpm ntl |
Binärdateien vom Skript ausführen | ntl | ntl | ntl | ntl |
dynamische Paketausführung | npx ntl | N/A | Yarn dlx ntl | pnpm dlx ntl |
runtime deps | npm i reagieren | Garn hinzufügen reagieren | wie klassisches | pnpm hinzufügen reagieren reagieren |
dev deps | npm i hinzufügen -D Babel-Alias: --save-dev | Garn add -D Babel-Alias: --dev | wie klassisches | pnpm, add -D babel alias: --save-dev |
füge deps zu package.json hinzu, ohne semver | npm i -E react alias: --save-exact | Yarn add -E react alias: --exact | wie Classic | pnpm -E React Alias hinzufügen: --save-exact |
Deps | deinstallieren | und | aus | package.json |
entfernen ohne Aktualisierung von package.json | npm uninstall --no-save | N/A | N/A | N/A |
In dieser Tabelle werden einige nützliche integrierte Befehle behandelt. Wenn es keinen offiziellen Befehl gibt, können Befehle von Drittanbietern normalerweise über npm
Pakete oder Yarn Berry
-Plugins verwendet werden.
Aktion | npm | Yarn Classic | Yarn Berry | pnpm |
---|---|---|---|---|
veröffentlichen | npm veröffentlichen | Garn veröffentlichen | Garn npm veröffentlichen | pnpm veröffentlichen |
Liste installiert deps | npm ls Alias: Liste, la, ll | Garnliste | pnpm list alias: ls | |
list veraltet deps | npm veraltetes | Garn veraltetes | Garn upgrade-interaktiv | pnpm veraltet |
Druckinformationen über Deps | npm erklären ntl Alias: warum | Garn warum ntl | wie klassisches | pnpm warum ntl |
init Projekt | npm init -y npm init (interaktiv) Alias: - -yes | Garn-Init -y Garn-Init (interaktiv) Alias: --yes | Garn-Init | pnpm-Init -y pnpm-Init (interaktiv) Alias: --yes |
Drucklizenzinformationen | N/A (über Drittanbieterpaket) | Garnlizenzliste | N/ A (oder über Plugin, anderes Plugin) | N/A (über Drittanbieterpaket) |
Paketmanagerversion aktualisieren | N/A (mit Tools von Drittanbietern, z. B. nvm) | mit npm: Yarn Policies Set-Version 1.13.0 | mit Corepack : Garnset Version 3.1.1 | N/A (mit npm |
, | Corepack | ) | ||
Führen | Sie | ein | Sicherheitsaudit | durch |
-E Reaktionsalias: --exact | wie klassisches | pnpm add -E Reaktionsalias: --save-exact | ||
Deps deinstallieren und aus package.json entfernen | npm uninstall Reaktionsalias: entfernen, rm, r, un, unlink | Garn entfernen reagieren | wie klassisches | Pnpm React-Alias entfernen: rm, un, uninstall |
deinstallieren deps ohne Aktualisierung von package.json | npm uninstall --no-save | N/A | N/A | N/A |
Die Konfiguration des Paketmanagers erfolgt in Ihrer package.json
und den dedizierten Konfigurationsdateien.
monorepo
Die meisten Konfigurationen erfolgen in der privaten Konfigurationsdatei .npmrc
.
Wenn Sie workspaces
Funktion von npm
verwenden möchten, müssen Sie das Workspaces-Metadatenfeld in package.json
hinzufügen, um npm mitzuteilen, wo sich das Unterprojekt oder der Workspace-Ordner befindet.
// ... „Arbeitsbereiche“: [ „Haken“, „Utilities“ ] }
Jeder Paketmanager kann die öffentliche npm
Registrierung verwenden. Sie möchten sie wahrscheinlich wiederverwenden, ohne sie in einem öffentlichen Register zu veröffentlichen. Sie können dies so konfigurieren, dass die Registrierung in Ihrer .npmrc
Datei privat ist. (Im Grunde haben jetzt alle private Quellen)
# .npmrc @doppelmutzi:registry=https://gitlab.doppelmutzi.com/api/v4/projects/41/packages/npm/
Es gibt viele Konfigurationsmöglichkeiten für npm
, am besten schauen Sie sich diese in der Dokumentation an.
Sie können workspaces
von yarn
in package.json
festlegen (muss ein privates Paket sein).
{ // ... „privat“: wahr, „workspaces“: [„workspace-a“, „workspace-b“] }
Jede optionale Konfiguration wird in eine .yarnrc
Datei geschrieben. Eine gängige Konfigurationsoption ist das Festlegen eines yarn-path:
Dadurch wird jedes Teammitglied gezwungen, eine bestimmte Binärversion zu verwenden. yarn-path
verweist auf den Ordner, der eine bestimmte Yarn
enthält (z. B. .yarn/releases/
). Sie können die einheitliche Yarn Classic
Version mit dem Befehl (classic.yarnpkg.com/en/docs/cli…) installieren.
Die Konfiguration workspaces
in Yarn Berry
ähnelt der Konfiguration in Yarn Classic
( package.json
). Die meisten Yarn Berry
-Konfigurationen finden in .yarnrc.yml
statt und es stehen zahlreiche Konfigurationsoptionen zur Verfügung.
# .yarnrc.yml YarnPath: .yarn/releases/yarn-3.1.1.cjs
yarn berry
kann die Importmethode $> yarn plugin import <name>
verwenden, um das Plug-In (yarnpkg.com/cli/plugin/…) zu erweitern, dieser Befehl wird Auch .yarnrc.yml
wird aktualisiert.
# .yarnrc.yml Plugins: - Pfad: .yarn/plugins/@yarnpkg/plugin-semver-up.cjs spec: „https://raw.githubusercontent.com/tophat/yarn-plugin-semver-up/master/bundles/%40yarnpkg/plugin-semver-up.js“
Wie im Verlaufsabschnitt erwähnt, aus Kompatibilitätsgründen Im strikten PnP-Modus kann es zu Problemen mit Abhängigkeiten kommen. Es gibt eine typische Lösung für diese Art von PnP-Problem: die Konfigurationsrichtlinie für Paketerweiterungen.
# .yarnrc.yml Paketerweiterungen: „styled-components@*“: Abhängigkeiten: React-is: „*“
pnpm
verwendet denselben Konfigurationsmechanismus wie npm
, sodass Sie .npmrc
Dateien verwenden können. Das Konfigurieren einer privaten Registrierung funktioniert ebenfalls genauso wie die Verwendung npm
. Projekte mit mehreren Paketen können mit der Workspace-Funktion von pnpm unterstützt werden. Um monorepo
zu initialisieren, müssen Sie den Speicherort des Pakets in der Datei pnpm-workspace.yaml
angeben.
# pnpm-workspace.yaml Pakete: - 'Pakete/**'
(Hier gibt es eigentlich drei Konzepte: einzelnes Warehouse und mehrere Projekte, einzelnes Warehouse und einzelnes Projekt sowie mehrere Warehouses und mehrere Projekte)
monorepo
ist ein Repository, das mehrere Projekte enthält. Diese Projekte werden workspace
oder Pakete genannt. Eine Projektorganisationsstrategie besteht darin, alles an einem Ort aufzubewahren, anstatt mehrere Repositories zu verwenden.
Dies führt natürlich zu zusätzlicher Komplexität. Yarn Classic
war das erste Unternehmen, das diese Funktion aktiviert hat, aber mittlerweile bietet jeder große Paketmanager Workspace-Funktionalität. In diesem Abschnitt wird gezeigt, wie Sie Ihren Arbeitsbereich mit den verschiedenen Paketmanagern konfigurieren.
Das npm
-Team hat die lang erwartete npm-Workspace-Funktion in Version 7 veröffentlicht. Es enthält viele CLI-Befehle, die bei der Verwaltung von Projekten mit mehreren Paketen vom Root-Paket aus helfen. Die meisten Befehle können mit workspace
Optionen verwendet werden, um npm
mitzuteilen, ob es für einen bestimmten, mehrere oder alle Arbeitsbereiche ausgeführt werden soll.
# Alle Abhängigkeiten für alle Arbeitsbereiche installieren $ npm i --workspaces. # gegen ein Paket ausführen $ npm test ausführen --workspace=hooks # gegen mehrere Pakete ausführen $ npm test ausführen --workspace=hooks --workspace=utils # gegen alle laufen $ npm test ausführen --workspaces #ignore alle Pakete, denen der Test fehlt $ npm run test --workspaces --if-present
Tipps: Im Vergleich zu anderen Paketmanagern unterstützt npm
v8 derzeit keine erweiterte Filterung oder parallele Ausführung mehrerer arbeitsbereichsbezogener Befehle.
Im August 2017 kündigte das Yarn
-Team monorepo
Unterstützung für Workspace-Funktionalität an. Bisher konnten Paketmanager nur in Projekten mit mehreren Paketen mit Software von Drittanbietern wie Lerna verwendet werden. Diese neue Ergänzung zu Yarn
ebnet auch anderen Paketmanagern den Weg, solche Funktionen zu implementieren.
Bei Interesse können Sie sich hier informieren, wie Sie die Workspace-Funktion von Yarn Classic mit und ohne Lerna nutzen können. In diesem Artikel werden jedoch nur einige notwendige Befehle vorgestellt, die Ihnen bei der Verwaltung von Abhängigkeiten in Yarn Classic
-Arbeitsbereich-Setup helfen.
# Installieren Sie alle Abhängigkeiten $yarn für alle Arbeitsbereiche # Informationen zum Abhängigkeitsbaum $ Yarn-Arbeitsbereiche anzeigen # Führen Sie ein anderes Paket aus, um $ Yarn Workspace Awesome - Paketstart zu starten # Webpack zum Paket hinzufügen $ Yarn Workspace Awesome - Paket hinzufügen - D Webpack # add React für alle Pakete $ Yarn add React -W
Yarn Berry
hat von Anfang an Arbeitsbereiche vorgestellt, da seine Implementierung auf den Konzepten von Yarn Classic
aufbaut. In einem Reddit-Kommentar gab der leitende Entwickler von Yarn Berry einen kurzen Überblick über arbeitsbereichsorientierte Funktionen, darunter:
Yarn Berry
verwendet eine Reihe von Protokollen, die im Feld dependencies
oder devDependencies
der Datei package.json
verwendet werden können. Darunter ist das workspace
Protokoll.
Im Gegensatz zum Arbeitsbereich von Yarn Classic
definiert Yarn Berry
klar, dass eine Abhängigkeit eines der Pakete in diesem monorepo
sein muss. Andernfalls versucht Yarn Berry
möglicherweise, seine Version aus der Remote-Registrierung abzurufen, wenn die Versionen nicht übereinstimmen.
{ // ... "Abhängigkeiten": { "@doppelmutzi/hooks": "workspace:*", „http-server“: „14.0.0“, // ... } }
Über das workspace
Protokoll hat pnpm
zu einem monorepo
Projekt ähnlich wie Yarn Berry
beigetragen. Viele pnpm
-Befehle akzeptieren die Optionen --recursive (-r)
oder --filter, die besonders im monorepo
-Kontext nützlich sind. Seine nativen Filterbefehle sind auch eine großartige Ergänzung zu Lerna
.
# Alle Arbeitsbereiche bereinigen pnpm -r exec -- rm -rf node_modules && rm pnpm-lock.yaml # alle Tests für alle Arbeitsbereiche mit dem Geltungsbereich @doppelmutzi ausführen pnpm recursive run test --filter @doppelmutzi/`
Die Leistung ist ein wichtiger Teil der Auswahlentscheidung. In diesem Abschnitt werden Benchmarks anhand eines kleinen und eines mittelgroßen Projekts vorgestellt. Hier einige Hinweise zum Beispielprojekt:
Ich habe jede unserer Paketmanager-Varianten einmal anhand von drei Anwendungsfällen gemessen. Für eine detaillierte Auswertung und Erläuterung sehen Sie sich bitte die Ergebnisse für Projekt 1 (P1) und Projekt 2 (P2) an.
node_modules
oder .pnp.cjs
node_modules
oder .pnp.cjs
node_modules
oder .pnp.cjs
habe ich das Tool gnomon verwendet, um die von der Installation verbrauchte Zeit zu messen ( yarn
| gnomon
). Zusätzlich habe ich die Größe der generierten Dateien $ du -sh node_modules
gemessen.
Leistungsergebnisse für Projekt 1 | |||||||
---|---|---|---|---|---|---|---|
Methode | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP lose 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,63 s | 108,89 | s 43,58 | s 31,77 s | 30,13 Sek | .56,64 | Sek.60,91 | Sek.
UC | 2 | 41,54 Sek | .65,49 | Sek. 26,43 Sek. 12,46 Sek. 12,66 Sek. 46,36 Sek. | 40,74 | Sek | . |
UC 3 | 23,59 Sek | . 40,35 Sek | . 20,32 Sek | . 1,61 | Sek.1,36 | Sek. 28,72 | Sek. 31. 8 9s |
Dateien und Größe | package-lock.json: 1,3 Mio. 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,5 Mio. | Knotenmodule: 395 Mio. Garn.Lock: 540 KB Cache: 68 Mio. | Knotenmodule: 374 Mio. Garn.Lock: 540 KB Cache: 68 Mio. |
Leistungsergebnisse für Projekt 2 | |||||||
---|---|---|---|---|---|---|---|
Methode | npm v8.1.2 | Yarn Classic v1.23.0 | pnpm v6.24.4 | Yarn Berry PnP lose 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,91 s | 43,26 | s 15,6 | s 13,92 s | 6,44 Sek | .23,62 | Sek.20,09 | Sek.
UC | 2 | 7,92 Sek | . 33,65 Sek. 8,86 Sek. 7,09Sek. | 5,63Sek | .15,12 | Sek.14,93 | Sek. |
UC 3 | 5,09 Sek | . 15,64 Sek | . 4,73 Sek | . 0,93 | Sek. 0,79 Sek. | 8,18 Sek | . 6,02 Sek. |
Dateien und Größe. | Paketsperre .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,0 M .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
ist im Umgang mit fehlerhaften Paketen etwas zu nachsichtig und ist auf einige Sicherheitslücken gestoßen, die sich direkt auf viele Projekte ausgewirkt haben. Wenn Sie beispielsweise in Version 5.7.0 den Befehl sudo npm
auf einem Linux-Betriebssystem ausführen, können Sie den Besitz von Systemdateien ändern, wodurch das Betriebssystem unbrauchbar wird.
Im Jahr 2018 ereignete sich ein weiterer Vorfall, bei dem es um den Diebstahl von Bitcoins ging. Das Node.js-Paket EventStream hat in seiner Version 3.3.6 eine schädliche Abhängigkeit hinzugefügt. Dieses Schadpaket enthält eine kryptografische Methode, die versucht, Bitcoins vom Computer des Entwicklers zu stehlen.
Um diese Probleme zu lösen, verwenden neue npm
Versionen kryptografische Algorithmen, um die Integrität Ihrer installierten Pakete zu überprüfen. SHA-512.
Yarn Classic
und Yarn Berry
verwenden Prüfsummen, um die Integrität jeder Packung von Anfang an zu überprüfen. Yarn
versucht außerdem zu verhindern, dass Sie schädliche Pakete abrufen, die nicht in package.json
deklariert sind: Wenn eine Nichtübereinstimmung festgestellt wird, wird die Installation abgebrochen.
Yarn Berry
weist im PnP-Modus nicht die Sicherheitsprobleme der herkömmlichen Methode node_modules
auf. Im Vergleich zu Yarn Classic
verbessert Yarn Berry
die Sicherheit der Befehlsausführung. Sie können nur Pakete ausführen, die in package.json
deklariert wurden. Diese Sicherheitsfunktion ähnelt pnpm
, das ich unten beschreibe.
pnpm
verwendet weiterhin Prüfsummen, um die Integrität jedes installierten Pakets zu überprüfen, bevor sein Code ausgeführt wird.
Wie oben erwähnt, haben sowohl npm
als auch Yarn Classic
aufgrund der Werbung Sicherheitsprobleme. pnpm
vermeidet diese Situation, da sein Verwaltungsmodell keine Erhöhung verwendet, sondern verschachtelte node_modules
Ordner generiert und so das Risiko eines illegalen Abhängigkeitszugriffs eliminiert. Dies bedeutet, dass Abhängigkeiten in .package.json
deklariert werden.
Wie wir besprochen haben, ist dies besonders wichtig in einer monorepo
-Umgebung, da Boosting-Algorithmen manchmal zu einem Abhängigkeits-Nichtdeterminismus führen können.
npm | Yarn Classic | Yarn Berry | pnpm |
Svelte | React | Jest (mit node_modules) | Vue 3 |
Preact | Angular | Storybook (mit node_modules) | Browserlist |
Express.js | Ember | Babel (mit node_modules) | Prisma |
Meteor | Next.js | Redux Toolkit (mit node_modules) | SvelteKit |
Apollo Server | Gatsby | ||
Nuxt | |||
Erstellen Sie eine Reaktions-App | |||
webpack-cli | |||
Emotion |
Tatsächlich gibt es große Unterschiede in den Prinzipien verschiedener Paketmanager.
pnpm
sieht zunächst wie npm
aus, als ihre CLI -Verwendung ähnlich ist, aber die Verwaltung pnpm
Abhängigkeiten ist sehr unterschiedlich. Yarn Classic
ist immer noch beliebt, gilt jedoch als Legacy -Software und Support kann in naher Zukunft fallen gelassen werden. Yarn Berry PnP
ist brandneu, aber sein Potenzial, die Weltverwalter -Welt -Welt erneut zu revolutionieren, ist noch nicht verwirklicht.
Im Laufe der Jahre haben viele Benutzer gefragt, wer die Paketmanager verwendet, und insgesamt scheinen sich die Menschen besonders für die Reife und Einführung von Yarn Berry PnP
zu interessieren.
Der Zweck dieses Artikels ist es, Ihnen mehrere Perspektiven zur Verfügung zu stellen, um zu entscheiden, welchen Paketmanager Sie für sich selbst verwenden sollen. Ich möchte darauf hinweisen, dass ich keinen bestimmten Paketmanager empfehle. Es hängt davon ab, wie Sie die unterschiedlichen Anforderungen abwägen - damit Sie trotzdem wählen können, was Sie möchten!
Englische Originaladresse: https://blog.logrocket.com/javascript-package-managers-compared/