Dieser Artikel sollte als All-in-One-Leitfaden für Node.js Lieblingskumpel dienen: npm.
Node.js erobert seit 2009 die Welt im Sturm. Hunderttausende von Systemen wurden mit Node.js erstellt, was die Entwicklergemeinde dazu veranlasste, zu behaupten, dass "JavaScript Software frisst".
Einer der Hauptfaktoren für den Erfolg von Node ist npm - sein beliebter Paketmanager, mit dem JavaScript-Entwickler nützliche Pakete wie lodash und moment schnell und einfach teilen können.
Ab dem Moment, in dem ich diesen Beitrag schreibe, hat npm die Veröffentlichung von über 1,3 Millionen Paketen mit einer wöchentlichen Download-Rate von über 16 Milliarden ermöglicht! Diese Zahlen sind für jedes Software-Tool fantastisch. Sprechen wir jetzt darüber, was genau npm ist.
Was ist NPM?
NPM - oder "Node Package Manager" - ist der Standardpaketmanager für die JavaScript-Laufzeit Node.js.
Es ist auch bekannt als "Ninja Pumpkin Mutants", "Nonprofit Pizza Makers" und eine Vielzahl anderer zufälliger Namen, die Sie bei npm-Erweiterungen erkunden und wahrscheinlich dazu beitragen können.
NPM besteht aus zwei Hauptteilen:
- ein CLI-Tool (Command-Line Interface) zum Veröffentlichen und Herunterladen von Paketen und
- Ein Online-Repository, das JavaScript-Pakete hostet
Für eine visuellere Erklärung können wir uns das Repository npmjs.com als ein Fulfillment-Center vorstellen, das Warenpakete von Verkäufern (Autoren von npm-Paketen) empfängt und diese Waren an Käufer (Benutzer von npm-Paketen) verteilt.
Um diesen Prozess zu vereinfachen, beschäftigt das Fulfillment-Center von npmjs.com eine Armee fleißiger Wombats (npm CLI), die jedem einzelnen Kunden von npmjs.com als persönliche Assistenten zugewiesen werden. Abhängigkeiten werden also wie folgt an JavaScript-Entwickler geliefert:

und der Prozess der Veröffentlichung eines Pakets für Ihre JS-Kollegen wäre ungefähr so:

Schauen wir uns an, wie diese Armee von Wombats Entwicklern hilft, die JavaScript-Pakete in ihren Projekten verwenden möchten. Wir werden auch sehen, wie sie Open-Source-Assistenten dabei helfen, ihre coolen Bibliotheken in die Welt zu bringen.
package.json
Jedes Projekt in JavaScript - ob es sich um Node.js oder eine Browseranwendung handelt - kann als npm-Paket mit eigenen Paketinformationen und seiner package.json
Aufgabe zur Beschreibung des Projekts definiert werden.
Wir können uns package.json
als gestempelte Etiketten auf diesen npm-guten Kisten vorstellen, die unsere Armee von Wombats liefert.
package.json
wird generiert, wenn npm init
es ausgeführt wird, um ein JavaScript / Node.js-Projekt mit diesen grundlegenden Metadaten zu initialisieren, die von Entwicklern bereitgestellt werden:
name
: Der Name Ihrer JavaScript-Bibliothek / Ihres JavaScript-Projektsversion
: die Version Ihres Projekts. Bei der Anwendungsentwicklung wird dieses Feld häufig vernachlässigt, da die Versionierung von OpenSource-Bibliotheken offensichtlich nicht erforderlich ist. Dennoch kann es als Quelle für die Bereitstellungsversion nützlich sein.description
: die Projektbeschreibunglicense
: die Projektlizenz
npm-Skripte
package.json
unterstützt auch eine scripts
Eigenschaft, die definiert werden kann, um Befehlszeilentools auszuführen, die im lokalen Kontext des Projekts installiert sind. Der scripts
Teil eines npm-Projekts kann beispielsweise folgendermaßen aussehen:
{ "scripts": { "build": "tsc", "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", "lint": "eslint src/**/*.ts", "pack": "ncc build", "test": "jest", "all": "npm run build && npm run format && npm run lint && npm run pack && npm test" } }
mit eslint
, prettier
, ncc
, jest
nicht unbedingt als globale ausführbaren Dateien installiert , sondern als lokal für Ihr Projekt innerhalb node_modules/.bin/
.
Die kürzlich eingeführte Einführung von npx ermöglicht es uns, diese node_modules
projektbezogenen Befehle wie ein global installiertes Programm durch Präfix npx ...
(dh npx prettier --write **/*.ts
) auszuführen .
Abhängigkeiten vs devDependencies
Diese beiden kommen in Form von Schlüsselwertobjekten mit den Namen der npm-Bibliotheken als Schlüssel und ihren semantisch formatierten Versionen als Wert. Dies ist ein Beispiel aus der TypeScript-Aktionsvorlage von Github:
{ "dependencies": { "@actions/core": "^1.2.3", "@actions/github": "^2.1.1" }, "devDependencies": { "@types/jest": "^25.1.4", "@types/node": "^13.9.0", "@typescript-eslint/parser": "^2.22.0", "@zeit/ncc": "^0.21.1", "eslint": "^6.8.0", "eslint-plugin-github": "^3.4.1", "eslint-plugin-jest": "^23.8.2", "jest": "^25.1.0", "jest-circus": "^25.1.0", "js-yaml": "^3.13.1", "prettier": "^1.19.1", "ts-jest": "^25.2.1", "typescript": "^3.8.3" } }
Diese Abhängigkeiten werden über den npm install
Befehl with --save
und --save-dev
flags installiert . Sie sollen für Produktions- bzw. Entwicklungs- / Testumgebungen verwendet werden. Wir werden uns im nächsten Abschnitt eingehender mit der Installation dieser Pakete befassen.
In der Zwischenzeit ist es wichtig, die möglichen Zeichen zu verstehen, die vor den semantischen Versionen auftreten (vorausgesetzt, Sie haben das major.minor.patch
Semver-Modell gelesen):
^
: neueste Nebenversion. Beispielsweise kann eine^1.0.4
Spezifikation eine Version installieren,1.3.0
wenn dies die neueste Nebenversion in der1
Hauptserie ist.~
: neueste Patch-Version. Auf die gleiche Weise wie^
bei Nebenversionen kann die~1.0.4
Spezifikation die Version installieren,1.0.7
wenn dies die neueste Nebenversion in der1.0
Nebenserie ist.
Alle diese genauen Paketversionen werden in einer generierten package-lock.json
Datei dokumentiert .
package-lock.json
Diese Datei beschreibt die genauen Versionen der Abhängigkeiten, die in einem npm-JavaScript-Projekt verwendet werden. Wenn package.json
es sich um ein generisches beschreibendes Etikett handelt, package-lock.json
handelt es sich um eine Zutatentabelle.
Und genau wie wir normalerweise die Inhaltsstofftabelle eines Produkts nicht lesen (es sei denn, Sie sind zu gelangweilt oder müssen es wissen), package-lock.json
ist es nicht dazu gedacht, von Entwicklern Zeile für Zeile gelesen zu werden (es sei denn, wir möchten es unbedingt lösen ". funktioniert in meiner Maschine "Probleme).
package-lock.json
wird normalerweise vom npm install
Befehl generiert und auch von unserem NPM-CLI-Tool gelesen, um die Reproduktion von Build-Umgebungen für das Projekt mit sicherzustellen npm ci
.
Wie man NPM Wombats effektiv als "Käufer" befiehlt
Wie aus den 1,3 Millionen veröffentlichten Paketen gegenüber 16 Milliarden Downloads hervorgeht, verwendet die Mehrheit der npm-Benutzer npm in dieser Richtung. Es ist also gut zu wissen, wie man dieses mächtige Werkzeug einsetzt.
npm installieren
Dies ist der am häufigsten verwendete Befehl, da wir heutzutage JavaScript / Node.js-Anwendungen entwickeln.
Standardmäßig npm install
wird die neueste Version eines Pakets mit dem ^
Versionszeichen installiert . Im npm install
Rahmen eines npm-Projekts werden Pakete node_modules
gemäß den package.json
Spezifikationen in den Projektordner heruntergeladen , wobei die Paketversion aktualisiert (und neu generiert package-lock.json
) wird, wo immer dies möglich ist, ^
und ~
Versionsübereinstimmung.
Sie können ein globales Flag angeben, -g
wenn Sie ein Paket im globalen Kontext installieren möchten, das Sie überall auf Ihrem Computer verwenden können (dies ist bei Befehlszeilen-Toolpaketen wie Live-Server üblich).
npm hat die Installation von JavaScript-Paketen so einfach gemacht, dass dieser Befehl häufig falsch verwendet wird. Dies führt dazu, dass npm der Hintern vieler Witze von Programmierern wie diesen ist:

Hier kommt die --production
Flagge zur Rettung! Im vorherigen Abschnitt haben wir die Verwendung in der Produktions- bzw. Entwicklungs- / Testumgebung erörtert dependencies
und vorgesehen devDependencies
. Mit diesem --production
Flag werden die Unterschiede in node_modules
gemacht.
By attaching this flag to the npm install
command, we will only install packages from dependencies
, thus drastically reducing the size of our node_modules
to whatever is absolutely necessary for our applications to be up and running.
Just like how as boy and girl scouts we didn't bring lemon squeezers to our lemonade booth, we shouldn't bring devDependencies
to production!
npm ci
So if npm install --production
is optimal for a production environment, must there be a command that's optimal for my local development, testing setup?
The answer is npm ci
.
Just like how if package-lock.json
doesn't already exist in the project it's generated whenever npm install
is called, npm ci
consumes this file to download the exact version of each individual package that the project depends on.
This is how we can make sure that the our project's context stays exactly the same across different machines, whether it's our laptops used for development or CI (Continuous Integration) build environments like Github Actions.
npm audit
With the humongous number of packages that have been published and can easily be installed, npm packages are susceptible to bad authors with malicious intentions like these.
Realising that there was an issue in the ecosystem, the npm.js organisation came up with the idea of npm audit
. They maintain a list of security loopholes that developers can audit their dependencies against using the npm audit
command.
npm audit
gives developers information about the vulnerabilities and whether there're versions with remediations to upgrade to. For example,

If the remediations are available in the next non-breaking version upgrades, npm audit fix
can be used to upgrade the affected dependencies' versions automatically.
How to effectively command NPM wombats as "seller"
We have gone through how to wield the NPM CLI tool as a consumer, but what about effectively using it as an author (and potentially becoming a JavaScript open source wizard ?)?
npm publish
Sending a package to our npmjs.com fulfillment centre is super easy as we only need to run npm publish
. The tricky part, which is not specific to npm package authors, is determining the version of the package.
The rule of thumb according to semver.org:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards compatible manner, and
- PATCH version when you make backwards compatible bug fixes.
It's even more important to follow the above rule when publishing your packages to ensure that you're not breaking anyone's code as the default version matching in npm is ^
(aka the next minor version).
❤️ npm ❤️ JavaScript ❤️ Node.js ❤️
That's all we need to know to start wielding npm effectively and command our lovely army of wombats!
