Qu'est-ce que npm? Un didacticiel Node Package Manager pour les débutants

Cet article devrait servir de guide essentiel tout-en-un pour le compagnon préféré de Node.js: npm.

Node.js prend d'assaut le monde depuis 2009. Des centaines de milliers de systèmes ont été construits à l'aide de Node.js, ce qui incite la communauté des développeurs à affirmer que «JavaScript mange des logiciels».

L'un des facteurs majeurs du succès de Node est npm - son gestionnaire de packages populaire, qui permet aux développeurs JavaScript de partager rapidement et facilement des packages utiles tels que lodash et moment.

Au moment où j'écris cet article, npm a facilité la publication de plus de 1,3 million de paquets avec un taux de téléchargement hebdomadaire de plus de 16 milliards! Ces chiffres sont fantastiques pour tout outil logiciel. Alors maintenant, parlons de ce qu'est exactement npm.

Qu'est-ce que NPM?

NPM - ou "Node Package Manager" - est le gestionnaire de packages par défaut pour l'exécution de JavaScript Node.js.

Il est également connu sous le nom de "Ninja Pumpkin Mutants", "Nonprofit Pizza Makers", et une foule d'autres noms aléatoires que vous pouvez explorer et probablement contribuer à des extensions npm.

NPM se compose de deux parties principales:

  • un outil CLI (interface de ligne de commande) pour la publication et le téléchargement de packages, et
  • un référentiel en ligne qui héberge des packages JavaScript

Pour une explication plus visuelle, nous pouvons considérer le référentiel npmjs.com comme un centre de distribution qui reçoit des colis de marchandises des vendeurs (auteurs de packages npm) et distribue ces produits aux acheteurs (utilisateurs de packages npm).

Pour faciliter ce processus, le centre de distribution de npmjs.com emploie une armée de wombats assidus (npm CLI) qui seront affectés en tant qu'assistants personnels à chaque client de npmjs.com. Les dépendances sont donc livrées aux développeurs JavaScript comme ceci:

et le processus de publication d'un package pour vos partenaires JS serait quelque chose comme ceci:

Voyons comment cette armée de wombats aide les développeurs qui souhaitent utiliser des packages JavaScript dans leurs projets. Nous verrons également comment ils aident les assistants open-source à diffuser leurs bibliothèques géniales dans le monde.

package.json

Chaque projet en JavaScript, qu'il s'agisse de Node.js ou d'une application de navigateur, peut être défini comme un package npm avec ses propres informations de package et son package.jsontravail pour décrire le projet.

Nous pouvons penser à des package.jsonétiquettes estampées sur ces bonnes boîtes npm que notre armée de Wombats livre.

package.jsonsera généré lors de l' npm initexécution pour initialiser un projet JavaScript / Node.js, avec ces métadonnées de base fournies par les développeurs:

  • name: le nom de votre bibliothèque / projet JavaScript
  • version: la version de votre projet. Souvent, pour le développement d'applications, ce champ est souvent négligé car il n'y a pas de besoin apparent de versioning des bibliothèques open source. Mais encore, cela peut être utile en tant que source de la version du déploiement.
  • description: la description du projet
  • license: la licence du projet

scripts npm

package.jsonprend également en charge une scriptspropriété qui peut être définie pour exécuter des outils de ligne de commande installés dans le contexte local du projet. Par exemple, la scriptspartie d'un projet npm peut ressembler à ceci:

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

avec eslint, prettier, ncc, jestpas nécessairement installé comme executables mondial mais aussi local à votre intérieur du projet node_modules/.bin/.

L'introduction récente de npx nous permet d'exécuter ces node_modulescommandes de projet tout comme un programme installé globalement en préfixant npx ...(ie npx prettier --write **/*.ts).

dépendances vs devDependencies

Ces deux éléments se présentent sous la forme d'objets clé-valeur avec les noms des bibliothèques npm comme clé et leurs versions au format sémantique comme valeur. Voici un exemple du modèle d'action TypeScript de 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" } } 

Ces dépendances sont installées via la npm installcommande avec --saveet --save-devindicateurs. Ils sont destinés à être utilisés respectivement pour les environnements de production et de développement / test. Nous approfondirons l'installation de ces packages dans la section suivante.

En attendant, il est important de comprendre les signes possibles qui précèdent les versions sémantiques (en supposant que vous ayez lu sur le major.minor.patchmodèle de semver):

  • ^: dernière version mineure. Par exemple, une ^1.0.4spécification peut installer la version 1.3.0s'il s'agit de la dernière version mineure de la 1série majeure.
  • ~: dernière version du correctif. De la même manière que ^pour les versions mineures, la ~1.0.4spécification peut installer la version 1.0.7s'il s'agit de la dernière version 1.0mineure de la série mineure.

Toutes ces versions de package exactes seront documentées dans un package-lock.jsonfichier généré .

package-lock.json

Ce fichier décrit les versions exactes des dépendances utilisées dans un projet JavaScript npm. Si package.jsonest une étiquette descriptive générique, package-lock.jsonest une table d'ingrédients.

Et tout comme nous ne lisons généralement pas le tableau des ingrédients d'un produit (à moins que vous ne vous ennuyiez trop ou que vous ayez besoin de savoir), il package-lock.jsonn'est pas destiné à être lu ligne par ligne par les développeurs (à moins que nous ne cherchions désespérément à résoudre " fonctionne dans mes problèmes de machine).

package-lock.jsonest généralement généré par la npm installcommande, et est également lu par notre outil CLI NPM pour assurer la reproduction des environnements de construction pour le projet avec npm ci.

Comment commander efficacement NPM Wombats en tant qu '«acheteur»

Comme déduit des 1,3 million de packages publiés contre 16 milliards de téléchargements mentionnés précédemment, la majorité des utilisateurs de npm utilisent npm dans cette direction. Il est donc bon de savoir utiliser cet outil puissant.

npm installer

Il s'agit de la commande la plus couramment utilisée lorsque nous développons des applications JavaScript / Node.js de nos jours.

Par défaut, npm install installe la dernière version d'un package avec le ^signe de version. Un npm installdans le cadre d'un projet de MNP télécharger les paquets dans le projet node_modulesde dossier selon les package.jsonspécifications, la mise à niveau de la version du package (et à son tour de régénération package-lock.json) partout où il peut sur la base ^et la ~correspondance des versions.

Vous pouvez spécifier un indicateur global -gsi vous souhaitez installer un package dans le contexte global que vous pouvez utiliser n'importe où sur votre machine (ceci est courant pour les packages d'outils de ligne de commande comme live-server).

npm a rendu l'installation des packages JavaScript si facile que cette commande est souvent utilisée de manière incorrecte. Cela fait que npm est la cible de nombreuses blagues de programmeurs comme celles-ci:

C'est là que le --productiondrapeau vient à la rescousse! Dans la section précédente, nous avons discuté dependencieset devDependenciesconçu pour une utilisation dans l'environnement de production et de développement / test respectivement. Ce --productiondrapeau est la façon dont les différences node_modulessont faites.

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:

  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 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!