Hvad er npm? En node-pakkehåndteringsvejledning til begyndere

Denne artikel skal tjene som en alt-i-en vigtig guide til Node.js 'foretrukne sidekick: npm.

Node.js har taget verden med storm siden 2009. Hundredtusinder af systemer er blevet bygget ved hjælp af Node.js, hvilket fik udviklerfællesskabet til at hævde, at "JavaScript spiser software".

En af de vigtigste faktorer for Nodes succes er npm - dens populære pakkehåndtering, der giver JavaScript-udviklere mulighed for at dele nyttige pakker som lodash og moment hurtigt og nemt.

Fra det øjeblik, jeg skriver dette indlæg, har npm muliggjort offentliggørelsen af ​​over 1,3 millioner pakker med en ugentlig downloadrate på over 16 milliarder! Disse tal er fantastiske til ethvert softwareværktøj. Så lad os nu tale om, hvad npm er.

Hvad er NPM?

NPM - eller "Node Package Manager" - er standardpakkehåndtering til JavaScript's runtime Node.js.

Det er også kendt som "Ninja Pumpkin Mutants", "Nonprofit Pizza Makers" og en række andre tilfældige navne, som du kan udforske og sandsynligvis bidrage til over ved npm-udvidelser.

NPM består af to hoveddele:

  • et CLI-værktøj (kommandolinjegrænseflade) til udgivelse og download af pakker og
  • et online arkiv, der er vært for JavaScript-pakker

For en mere visuel forklaring kan vi tænke på lageret npmjs.com som et opfyldelsescenter, der modtager pakker med varer fra sælgere (npm pakkeforfattere) og distribuerer disse varer til købere (npm-pakkebrugere).

For at lette denne proces anvender npmjs.com-opfyldelsescentret en hær af hårdtarbejdende wombats (npm CLI), der vil blive tildelt som personlige assistenter til hver enkelt npmjs.com-kunde. Så afhængigheder leveres til JavaScript-udviklere som denne:

og processen med at udgive en pakke til dine JS-kammerater ville være sådan noget:

Lad os se på, hvordan denne hær af wombats hjælper udviklere, der ønsker at bruge JavaScript-pakker i deres projekter. Vi ser også, hvordan de hjælper open source-guider med at få deres seje biblioteker ud i verden.

pakke.json

Hvert projekt i JavaScript - hvad enten det er Node.js eller en browserapplikation - kan afgrænses som en npm-pakke med sin egen pakkeinformation og sit package.jsonjob til at beskrive projektet.

Vi kan tænke på package.jsonsom stemplede etiketter på de npm gode kasser, som vores hær af Wombats leverer rundt.

package.jsonvil blive genereret, når npm initdet køres for at initialisere et JavaScript / Node.js-projekt med disse grundlæggende metadata leveret af udviklere:

  • name: navnet på dit JavaScript-bibliotek / projekt
  • version: versionen af ​​dit projekt. Ofte forsømmes dette felt ofte til applikationsudvikling, da der ikke er noget tilsyneladende behov for versionering af open source-biblioteker. Men stadig kan det komme praktisk som en kilde til implementeringsversionen.
  • description: projektets beskrivelse
  • license: projektets licens

npm-scripts

package.jsonunderstøtter også en scriptsegenskab, der kan defineres til at køre kommandolinjeværktøjer, der er installeret i projektets lokale kontekst. For eksempel kan den scriptsdel af et npm-projekt se sådan ud:

{ "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" } } 

med eslint, prettier, ncc, jestikke nødvendigvis installeret som globale eksekverbare men snarere som lokale til dit projekt indeni node_modules/.bin/.

Den nylige introduktion af npx giver os mulighed for at køre disse node_modulesprojektomfangede kommandoer ligesom et globalt installeret program ved at prefiksere npx ...(dvs. npx prettier --write **/*.ts).

afhængigheder vs devAfhængigheder

Disse to kommer i form af nøgleværdigenstande med npm-bibliotekernes navne som nøglen og deres semantisk-formaterede versioner som værdien. Dette er et eksempel fra Githubs TypeScript Action-skabelon:

{ "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" } } 

Disse afhængigheder installeres via npm installkommandoen med --saveog --save-devflag. De er beregnet til at blive brugt til henholdsvis produktion og udvikling / testmiljøer. Vi vil gå nærmere ind på installationen af ​​disse pakker i det næste afsnit.

I mellemtiden er det vigtigt at forstå de mulige tegn, der kommer før de semantiske versioner (forudsat at du har læst op på major.minor.patchmodel af semver):

  • ^: seneste mindre udgivelse. For eksempel kan en ^1.0.4specifikation muligvis installere version, 1.3.0hvis det er den seneste mindre version i den 1store serie.
  • ~: seneste patchudgivelse. På samme måde som ^for mindre udgivelser, kan ~1.0.4specifikationen muligvis installere version, 1.0.7hvis det er den seneste mindre version i den 1.0mindre serie.

Alle disse nøjagtige pakkeversioner vil blive dokumenteret i en genereret package-lock.jsonfil.

package-lock.json

Denne fil beskriver de nøjagtige versioner af afhængigheder, der bruges i et npm JavaScript-projekt. Hvis package.jsoner en generisk beskrivende etiket, package-lock.jsoner en ingrediens tabel.

Og ligesom hvordan vi normalt ikke læser ingredienstabellen for et produkt (medmindre du er for keder eller har brug for at vide), package-lock.jsoner det ikke meningen, at det skal læses linje for linje af udviklere (medmindre vi er desperate efter at løse fungerer i min maskine "udgaver).

package-lock.jsongenereres normalt af npm installkommandoen og læses også af vores NPM CLI-værktøj for at sikre reproduktion af byggemiljøer til projektet med npm ci.

Sådan effektivt kommanderer NPM Wombats som en "køber"

Som det fremgår af de 1,3 millioner offentliggjorte pakker mod 16 milliarder downloads, der er nævnt tidligere, bruger størstedelen af ​​npm-brugere npm i denne retning. Så det er godt at vide, hvordan man bruger dette kraftfulde værktøj.

npm installation

Dette er den mest anvendte kommando, da vi udvikler JavaScript / Node.js-applikationer i dag.

npm install Installerer som standard den nyeste version af en pakke med ^versionstegnet. En npm installinden for rammerne af et npm-projekt vil downloade pakker i projektets node_modulesmappe i henhold til package.jsonspecifikationerne, opgradere pakkeversionen (og til gengæld regenerere package-lock.json), hvor det kan, baseret på ^og ~versionstilpasning.

Du kan angive et globalt flag, -ghvis du vil installere en pakke i den globale sammenhæng, som du kan bruge overalt på din maskine (dette er almindeligt for kommandolinjeværktøjspakker som live-server).

npm har gjort installation af JavaScript-pakker så let, at denne kommando ofte bruges forkert. Dette resulterer i, at npm er baghovedet på mange programmeringsvittigheder som disse:

Det er her, --productionflaget kommer til undsætning! I det foregående afsnit diskuterede dependenciesog devDependenciesbetød vi brug i henholdsvis produktion og udvikling / testmiljø. Dette --productionflag er, hvordan forskellene i node_moduleser lavet.

Ved at vedhæfte dette flag til npm installkommandoen vil vi kun installere pakker fra dependencies, hvilket drastisk reducerer størrelsen på vores node_modulestil det, der er absolut nødvendigt for, at vores applikationer kan køre.

Ligesom hvordan vi som dreng- og pigespejdere ikke bragte citronpressere til vores limonadekabine, vi skulle ikke bringe devDependenciestil produktion!

npm ci

Så hvis der npm install --productioner optimalt for et produktionsmiljø, skal der være en kommando, der er optimal for min lokale udvikling, testopsætning?

Svaret er npm ci.

Ligesom hvordan hvis package-lock.jsonikke der allerede findes i projektet, det genereres, når npm installder kaldes, npm cibruger denne fil til at downloade den nøjagtige version af hver enkelt pakke, som projektet afhænger af.

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:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards compatible manner, and
  3. PATCH-version, når du foretager bagudkompatible fejlrettelser.

Det er endnu vigtigere at følge ovenstående regel, når du udgiver dine pakker for at sikre, at du ikke bryder nogens kode, da standardversionen matcher i npm er ^(aka den næste mindre version).

❤️ npm ❤️ JavaScript ❤️ Node.js ❤️

Det er alt, hvad vi har brug for at vide for at begynde at bruge npm effektivt og kommandere vores dejlige hær af wombats!