Der Autor des Materials, dessen Übersetzung wir heute veröffentlichen, sagt, dass eines der Probleme, mit denen sich Programmierer befassen müssen, darin besteht, dass ihr Code für sie funktioniert und jemand anderem Fehler gibt. Dieses Problem, möglicherweise eines der häufigsten, entsteht aufgrund der Tatsache, dass verschiedene Abhängigkeiten, die das Programm verwendet, in den Systemen des Erstellers und Benutzers des Programms installiert sind. Um diesem Phänomen entgegenzuwirken, existieren in den 
Garn- und 
npm- Paketmanagern sogenannte Sperrdateien. Sie enthalten Informationen zu den genauen Versionen der Abhängigkeiten. Der Mechanismus ist nützlich, aber wenn jemand ein Paket entwickelt, das in npm veröffentlicht werden soll, sollte er keine Sperrdateien verwenden. Dieses Material widmet sich der Geschichte, warum dies so ist.

Das Wichtigste auf den Punkt gebracht
Sperrdateien sind äußerst nützlich, wenn Sie Node.js-Anwendungen wie Webserver entwickeln. Wenn Sie jedoch über das Erstellen einer Bibliothek oder eines Befehlszeilentools mit dem Ziel der Veröffentlichung in npm sprechen, müssen Sie wissen, dass Sperrdateien in npm nicht veröffentlicht werden. Wenn diese Dateien während der Entwicklung verwendet werden, verwenden der Ersteller des npm-Pakets und diejenigen, die dieses Paket verwenden, unterschiedliche Versionen der Abhängigkeiten.
Was ist eine Sperrdatei?
Die Sperrdatei beschreibt den vollständigen Abhängigkeitsbaum in der Form, die er während der Arbeit am Projekt erhalten hat. Diese Beschreibung enthält auch verschachtelte Abhängigkeiten. Die Datei enthält Informationen zu bestimmten Versionen der verwendeten Pakete. Im npm-Paketmanager werden solche Dateien in yarn - 
yarn.lock als 
package-lock.json yarn.lock . In beiden Managern befinden sich diese Dateien im selben Ordner wie 
package.json .
So könnte 
package-lock.json aussehen.
 { "name": "lockfile-demo", "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": {  "ansi-styles": {    "version": "3.2.1",    "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",    "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",    "requires": {      "color-convert": "^1.9.0"    }  },  "chalk": {    "version": "2.4.2",    "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",    "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",    "requires": {      "ansi-styles": "^3.2.1",      "escape-string-regexp": "^1.0.5",      "supports-color": "^5.3.0"    }  } } } 
Hier ist ein Beispiel für eine 
yarn.lock Datei. Es ist nicht wie 
package-lock.json , enthält jedoch ähnliche Daten.
 # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies:       color-convert "^1.9.0" chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies:       ansi-styles "^3.2.1"       escape-string-regexp "^1.0.5"       supports-color "^5.3.0" 
Beide Dateien enthalten einige wichtige Abhängigkeitsinformationen:
- Die genaue Version jeder installierten Abhängigkeit.
- Abhängigkeitsinformationen für jede Abhängigkeit.
- Informationen zum heruntergeladenen Paket, einschließlich der Prüfsumme zur Überprüfung der Integrität des Pakets.
Wenn alle Abhängigkeiten in der Sperrdatei aufgeführt sind, warum fügen sie dann auch Informationen zu 
package.json ? Warum werden zwei Dateien benötigt?
Vergleich von package.json und Sperrdateien
Der Zweck des 
dependencies der Datei 
package.json besteht darin, die Projektabhängigkeiten 
package.json , die installiert werden müssen, damit sie ordnungsgemäß funktionieren. Dies beinhaltet jedoch keine Informationen über die Abhängigkeiten dieser Abhängigkeiten. Abhängigkeitsinformationen können genaue Paketversionen oder einen bestimmten Versionsbereich enthalten, der gemäß den Regeln der 
semantischen Versionierung angegeben wurde . Bei Verwendung des Npm- oder Garnbereichs wird die am besten geeignete Version des Pakets ausgewählt.
Angenommen, der Befehl 
npm install wurde ausgeführt, um die Abhängigkeiten eines bestimmten Projekts zu installieren. Während des Installationsprozesses nahm npm geeignete Pakete auf. Wenn Sie diesen Befehl nach einer Weile erneut ausführen und während dieser Zeit neue Versionen von Abhängigkeiten freigegeben werden, kann es durchaus vorkommen, dass beim zweiten Mal andere Versionen der im Projekt verwendeten Pakete geladen werden. Wenn Sie beispielsweise eine Abhängigkeit wie 
twilio mit dem 
npm install twilio der folgende Eintrag im Abschnitt " 
dependencies " der Datei 
package.json :
 { "dependencies": {    "twilio": "^3.30.3" } } 
Wenn Sie sich die 
Dokumentation zur semantischen Versionierung von npm ansehen, sehen Sie, dass das Symbol 
^ angibt, dass eine beliebige Version des Pakets geeignet ist, deren Anzahl größer oder gleich 3.30.3 und kleiner als 4.0.0 ist. Wenn das Projekt keine Sperrdatei enthält und eine neue Version des Pakets freigegeben wird, 
yarn install npm install oder 
yarn install install diese neue Version des Pakets automatisch. Die Informationen in 
package.json werden nicht aktualisiert. Bei Verwendung von Sperrdateien sieht alles anders aus.
Wenn npm oder yarn die entsprechende Sperrdatei findet, werden Pakete basierend auf dieser Datei und nicht auf 
package.json . Dies ist beispielsweise besonders nützlich, wenn Sie CI-Systeme (Continuous Integration) auf Plattformen verwenden, auf denen Sie einen einheitlichen Betrieb von Code und Tests in einer Umgebung sicherstellen müssen, deren Eigenschaften im Voraus bekannt sind. In solchen Fällen können Sie beim Aufrufen der entsprechenden Paketmanager spezielle Befehle oder Flags verwenden:
 npm ci #   ,    package-lock.json yarn install --frozen-lock-file #  ,    yarn.lock,     
Dies ist äußerst nützlich, wenn Sie ein Projekt wie eine Webanwendung oder einen Server entwickeln, da Sie in einer CI-Umgebung das Benutzerverhalten simulieren müssen. Wenn wir eine Sperrdatei in das Projekt-Repository aufnehmen (z. B. mit Git-Tools erstellt), können wir daher sicher sein, dass jeder Entwickler, jeder Server, jedes Code-Building-System und jede CI-Umgebung dieselben Versionen verwendet Abhängigkeiten.
Warum nicht dasselbe tun, wenn Sie Bibliotheken oder andere Softwaretools in der npm-Registrierung veröffentlichen? Bevor wir diese Frage beantworten, müssen wir darüber sprechen, wie das Veröffentlichen von Paketen funktioniert.
Paketveröffentlichungsprozess
Einige Entwickler glauben, dass das, was in npm veröffentlicht wird, genau das ist, was im Git-Repository gespeichert ist oder was das Projekt nach Abschluss der Arbeit daran wird. Dies ist eigentlich nicht der Fall. Beim Veröffentlichen eines Pakets ermittelt npm 
package.json des 
.npmignore in der Datei 
package.json und der Datei 
.npmignore , welche Dateien veröffentlicht werden 
.npmignore . Wenn nichts davon erkannt werden kann, wird die 
.gitignore Datei verwendet. Außerdem werden einige Dateien immer veröffentlicht, andere nie. Was diese Dateien sind, finden Sie 
hier . Beispielsweise ignoriert npm immer den Ordner 
.git .
Danach nimmt npm alle entsprechenden Dateien und 
packt sie mit dem Befehl 
npm pack in eine 
tarball Datei. Wenn Sie sich ansehen möchten, was genau in eine solche Datei gepackt ist, können Sie den Befehl 
npm pack --dry-run im Projektordner 
npm pack --dry-run und die Liste der Materialien in der Konsole 
npm pack --dry-run .
Npm pack - Befehlsausgabe trocken ausführenDie resultierende 
tarball Datei wird dann in die npm-Registrierung hochgeladen. Wenn Sie den 
npm pack --dry-run Sie darauf achten, dass eine Datei 
package-lock.json im Projekt nicht in der Tarball-Datei enthalten ist. Dies liegt daran, dass diese Datei gemäß den npm- 
Regeln immer ignoriert wird.
Das Ergebnis ist, dass die Datei 
package-lock.json nicht beteiligt ist, wenn jemand das Paket eines anderen installiert. Was sich in dieser Datei befindet, das der Paketentwickler hat, wird bei der Installation des Pakets durch eine andere Person nicht berücksichtigt.
Dies kann durch unglücklichen Zufall zu dem Problem führen, über das wir am Anfang gesprochen haben. Im Entwicklersystem funktioniert der Code einwandfrei und in anderen Systemen führt er zu Fehlern. Tatsache ist jedoch, dass der Projektentwickler und diejenigen, die das Projekt verwenden, unterschiedliche Versionen der Pakete verwenden. Wie kann ich das beheben?
Ablehnung von Sperrdateien und Verwendung von Technologie-Schrumpffolie
Zuerst müssen Sie verhindern, dass Sperrdateien in das Projekt-Repository aufgenommen werden. Wenn Sie git verwenden, müssen Sie Folgendes in Ihre 
.gitignore Projektdatei 
.gitignore :
 yarn.lock package-lock.json 
In der 
yarn.lock heißt es, dass 
yarn.lock zum Repository hinzugefügt werden muss, auch wenn es um die Entwicklung der Bibliothek geht, die Sie veröffentlichen 
yarn.lock . Wenn Sie jedoch möchten, dass Sie und Ihre Bibliotheksbenutzer mit demselben Code arbeiten, würde ich empfehlen, 
yarn.lock in die 
.gitignore Datei aufzunehmen.
Sie können die automatische Erstellung der Datei 
package-lock.json deaktivieren, 
.npmrc Datei 
.npmrc mit dem folgenden Inhalt zum Projektordner 
.npmrc :
 package-lock=false 
Wenn Sie mit Garn arbeiten, können Sie den 
yarn install --no-lockfile , mit dem Sie das Lesen der Datei 
yarn.lock deaktivieren können.
Die Tatsache, dass wir die Datei 
package-lock.json , bedeutet jedoch nicht, dass wir keine Informationen über Abhängigkeiten und verschachtelte Abhängigkeiten erfassen können. Es 
gibt eine andere Datei namens 
npm-shrinkwrap.json .
Im Allgemeinen ist dies 
dieselbe Datei wie 
package-lock.json . Sie wird mit dem 
npm shrinkwrap . Diese Datei wird in die npm-Registrierung aufgenommen, wenn das Paket veröffentlicht wird.
Um diesen Vorgang zu automatisieren, kann der 
npm shrinkwrap als Prepack-Skript zum 
package.json Datei package.json hinzugefügt werden. Sie können den gleichen Effekt mit dem Git-Commit-Hook erzielen. Auf diese Weise können Sie sicher sein, dass in Ihrer Entwicklungsumgebung, in Ihrem CI-System und den Benutzern Ihres Projekts dieselben Abhängigkeiten verwendet werden.
Es ist erwähnenswert, dass empfohlen wird, diese Technik verantwortungsbewusst anzuwenden. Durch das Erstellen von Shrinkwrap-Dateien schreiben Sie bestimmte Versionen der Abhängigkeiten fest. Dies ist einerseits nützlich, um den stabilen Betrieb des Projekts sicherzustellen, andererseits kann es Benutzer daran hindern, kritische Patches zu installieren, was andernfalls automatisch erfolgen würde. Tatsächlich empfiehlt npm dringend, bei der Entwicklung von Bibliotheken keine Shrinkwrap-Dateien zu verwenden, um deren Verwendung auf CI-Systeme zu beschränken.
Suchen von Paket- und Abhängigkeitsinformationen
Leider ist es bei all den zahlreichen Informationen zum Abhängigkeitsmanagement in der npm- 
Dokumentation manchmal schwierig, in diesen Informationen zu navigieren. Wenn Sie wissen möchten, was genau während der Installation von Abhängigkeiten installiert oder 
--dry-run wird, bevor Sie das Paket an npm senden, können Sie mit verschiedenen Befehlen das 
--dry-run verwenden. Die Verwendung dieses Flags führt dazu, dass das Team das System nicht beeinflusst. Beispielsweise 
npm install --dry-run Befehl 
npm install --dry-run die Abhängigkeiten nicht tatsächlich, und der Befehl 
npm publish --dry-run startet den Paketveröffentlichungsprozess nicht.
Hier sind einige ähnliche Befehle:
 npm ci --dry-run #  ,   package-lock.json   npm-shrinkwrap.json npm pack --dry-run #     ,       npm install <dep> --verbose --dry-run #            
Zusammenfassung
Vieles, worüber wir hier gesprochen haben, hängt von den Besonderheiten der Ausführung verschiedener Operationen mit npm ab. Wir sprechen über das Verpacken, Veröffentlichen, Installieren von Paketen und das Arbeiten mit Abhängigkeiten. Und angesichts der Tatsache, dass sich npm ständig weiterentwickelt, können wir sagen, dass sich dies alles in Zukunft ändern kann. Darüber hinaus hängt die Möglichkeit der praktischen Anwendung der hier gegebenen Empfehlungen davon ab, wie der Paketentwickler das Problem der Verwendung unterschiedlicher Versionen von Abhängigkeiten in unterschiedlichen Umgebungen wahrnimmt.
Hoffentlich hat Ihnen dieses Material geholfen, besser zu verstehen, wie das npm-Abhängigkeits-Ökosystem funktioniert. Wenn Sie sich noch eingehender mit dieser Frage befassen möchten, können Sie 
hier die Unterschiede zwischen den 
npm install npm ci und 
npm install nachlesen. 
Hier erfahren Sie, was genau in die 
npm-shrinkwrap.json package-lock.json und 
npm-shrinkwrap.json . 
Auf der npm-Dokumentationsseite können Sie herausfinden, welche Projektdateien in Paketen enthalten sind und welche nicht.
Liebe Leser! Verwenden Sie die Datei npm-shrinkwrap.json in Ihren Projekten?
