Yarn2 – schneller, stabiler und moderner

Seite 2: Die Unterschiede zwischen Yarn1 und Yarn2

Inhaltsverzeichnis

Die erste Abweichung zur vorherigen Hauptversion fällt direkt beim Verwenden der Kommandozeile auf. Wo Version 1 noch mit zahlreichen Emojis zur Auflockerung gearbeitet hat, ist die Ausgabe der neuen Version deutlich nüchterner gestaltet. Der Grund hierfür ist, dass die Entwickler den Fokus auf Benutzbarkeit und Klarheit gelegt haben. Deshalb gibt auch jede Zeile einen Code an. Diese Fehlercodes sollen es einfacher machen, die Lösung eines Problems in der Dokumentation nachzuschlagen.

Installationsprozess eines Pakets (Abb. 1)

Weitere Änderungen sind für den Benutzer des Paketmanagers nicht direkt ersichtlich. Allerdings haben die Yarn-Entwickler beispielsweise die gesamte Codebasis vom Flow-Typsystem auf TypeScript umgestellt. Das macht die Werkzeugunterstützung für die Entwicklung des Paketmanagers und von Plug-ins deutlich komfortabler.

Eine weitere strukturelle Änderung betrifft die Lock- und Konfigurationsdateien von Yarn. Bisher waren sie in einem Format, das YAML zwar ähnlich war, aber dennoch nicht dem Standard folgte. Die nun erfolgte Anpassung erleichtert es Entwicklern, die Konfigurationsdateien zu ändern, da sie nicht mehr den gesonderten YAML-Dialekt beachten müssen. Das vereinfacht ebenfalls die Verarbeitung der Dateien durch andere Applikationen, die nun standardkonforme YAML-Parser einsetzen können.

Das als strikte Paketgrenzen bezeichnete Feature kann beim Umstieg auf die neue Version von Yarn zu Problemen führen. Dahinter verbirgt sich die Tatsache, dass ein Paket lediglich Pakete verwenden darf, die es explizit als Abhängigkeiten aufgeführt hat. Während der Entwicklung erscheint es als selbstverständlich, ein Paket vor der Verwendung zu installieren. Hat ein anderes Paket das benötigte jedoch bereits installiert, kann die Applikation es über das Modulsystem laden – es befindet sich schließlich schon im aktuellen Projekt.

Oft nennt man solche Pakete PeerDependencies, da Entwickler sie ohne die Abhängigkeiten nicht sinnvoll betreiben können. Greift ein Paket auf eine nicht aufgeführte Abhängigkeit zu, wirft Yarn einen Fehler, da es gegen die strikten Paketgrenzen verstößt. Unterliegt das betroffene Paket dem eigenen Einflussbereich, besteht kein Problem, da man die Abhängigkeit einfach eintragen kann.

Anders ist der Fall, wenn es sich um ein externes Paket handelt. Dann müssen die Maintainer daran arbeiten. In einigen Fällen ist es jedoch nicht denkbar, mit der Verwendung eines Pakets zu warten. Dazu bietet Yarn die Möglichkeit, das Problem über eine paketspezifische Konfiguration zu lösen, sodass die Installation ohne Fehlermeldung erfolgen kann. Sie erfolgt in der ".yarnrc.yml"-Datei unter der packageExtensions-Einstellung. Anwender können pro installiertem Paket zusätzliche Erweiterungen angeben, beispielsweise fehlende Abhängigkeiten.

Ein Feature, das die Verwendung von Yarn weiter beschleunigt, ist das Build Dependency Tracking. Bisher hat Yarn Pakete, die über einen eigenen Build-Prozess verfügen, bei Änderungen am Projekt komplett neu gebaut. Die neue Funktion hält den Status der Pakete fest. Der Build erfolgt nur noch, wenn sich der Abhängigkeitsbaum des Pakets ändert.

Ein häufiges Problem ist die Inkompatibilität der Kommandozeilen auf verschiedenen Betriebssystemen, auf denen Entwickler die Skripte der "package.json"-Datei ausführen. Yarn löst es, indem ein über die Systeme normalisierter Shell-Interpreter Bestandteil des Paketmanagers ist. Er verfügt zwar nicht über den gesamten Funktionsumfang einer vollwertigen Shell, deckt jedoch einen Großteil der Anwendungsfälle ab.

Yarn dlx

Eine weitere Neuerung ist die Einführung des dlx-Kommandos. dlx steht für "Download and Execute". Der Befehl lädt das angegebene Paket herunter und führt es aus. Ein typischer Vertreter eines solchen Pakets ist json-server, ein einfacher Schnittstellenserver, der den Inhalt einer JSON-Datei als Restful-API anbietet. Entwickler können ihn mit folgendem Befehl starten:

yarn dlx json-server data.json

Beim Ausführen prüft Yarn, ob das Paket bereits im lokalen Cache vorhanden ist. Zunächst ist das nicht der Fall und Yarn lädt den json-server aus dem Paket-Repository herunter. Bei jeder weiteren Ausführung entfällt der Schritt, was den Start des Serverprozesses deutlich beschleunigt.

Der yarn dlx-Befehl funktioniert ähnlich wie npx, mit dem Unterschied, dass yarn dlx lediglich Pakete herunterlädt und ausführt, nicht aber automatisch auf dem lokalen System nach Paketen sucht. Der Grund für das unterschiedliche Verhalten liegt darin, dass die striktere Variante von yarn dlx potenzielle Sicherheitsprobleme reduzieren soll. Bei npx können Entwickler nicht sicherstellen, ob der Befehl in der lokalen oder der Netzwerkvariante abläuft. In Yarn ist das ganz klar getrennt. yarn run bezieht die Skripte aus lokalen Quellen in Form der scripts-Sektion der package.json, lokal installierten Paketen mit ausführbaren Dateien oder einer lokalen Skriptdatei.

Der Begriff Zero Installs bezeichnet eine Bestrebung des Paketmanagers, die Installation von Abhängigkeiten einer Applikation so schnell und stabil wie möglich zu gewährleisten. Vor der Einführung von Lock-Dateien war das nur auf der Ebene der obersten Abhängigkeiten in der "package.json"-Datei garantiert. Mit den Lock-Dateien wurden die Versionen aller installierten Pakete festgelegt.

Yarn geht mit Zero Installs noch einen Schritt weiter und speichert den Paket-Cache als Bestandteil des Repositorys. Das bedeutet, dass die bisherige Empfehlung, die Abhängigkeiten nicht einzuchecken, damit hinfällig ist. Alle Abhängigkeiten im Repository zu haben, beschleunigt nicht nur die Installation der Applikation, sondern macht sie auch deutlich stabiler. Es ist keine Verbindung zu einem externen Dienst wie einem zentralen Package-Repository mehr notwendig. Damit ist die Installation einer JavaScript-Applikation nicht mehr von externen Faktoren abhängig und kann auch in einem abgeschotteten Netz ohne Internetverbindung ablaufen.

Nachteile gibt es dennoch: Gerade bei umfangreichen Applikationen mit einer großen Anzahl von Dependencys steigt die Repository-Größe stark an. Deshalb speichert Yarn die Pakete in komprimierter Form.

In der Dokumentation ziehen die Entwickler von Yarn einen Vergleich zu NPM, bei dem 135 000 unkomprimierte Dateien mit einer Größe von 1,2 GByte in Yarn 2000 komprimierten Archiven mit einer Größe von 139 MByte entsprechen. Das lokale Cache ist als read-only implementiert. Die Pakete können ihn nur lesen, ein Ändern des Inhalts ist nicht ohne weiteres möglich.

Da das Zero-Installs-Konzept nicht nur Vorteile hat, lässt es sich über die Konfigurationsoption enableGlobalCache deaktivieren.