
Cours d'entrée à la maîtrise front-end (vue) : Entrer dans l'apprentissage
De nos jours, les étudiants en développement front-end ne peuvent pas se passer de npm , un outil de gestion de packages. Son excellent mécanisme de gestion des versions de packages porte toute la prospère communauté NodeJS . pour comprendre son mécanisme interne. Cela nous aide à approfondir notre compréhension du développement de modules et des diverses configurations d'ingénierie frontales pour accélérer notre dépannage (je crois que de nombreux étudiants ont été troublés par divers problèmes de dépendance).
Cet article effectue une analyse détaillée du mécanisme de gestion des packages de npm sous trois angles : package.json , gestion des versions, installation des dépendances et exemples spécifiques.

Dans Node.js , un module est une bibliothèque ou un framework et également un projet Node.js Le projet Node.js suit une architecture modulaire. Lorsque l'on crée un projet Node.js , cela signifie créer un module. Ce module doit avoir un fichier de description, à savoir package.json . Il s'agit de notre fichier de configuration le plus courant, mais avez-vous vraiment compris sa configuration en détail ? La configuration d'un fichier package.json raisonnable détermine directement la qualité de notre projet, nous allons donc d'abord analyser la configuration détaillée de package.json .
Il existe de nombreux attributs dans package.json , parmi lesquels seulement deux doivent être renseignés : name et version . Ces deux attributs forment l'identifiant unique d'un module npm .
name le nom du module. Lors de la dénomination, vous devez suivre certaines spécifications et recommandations officielles :
le nom du package deviendra un paramètre dans l' url du module, la ligne de commande ou un nom de url . sont dans le nom du package. Aucun des deux ne peut être utilisé. Vous pouvez utiliser validate-npm-package-name pour vérifier si le nom du package est légal.
Les noms de packages sémantiques peuvent aider les développeurs à trouver plus rapidement les packages requis et à éviter d'obtenir accidentellement le mauvais package.
S'il y a des symboles dans le nom du package, les symboles ne doivent pas être répétés avec le nom du package existant après les avoir supprimés.
Par exemple : puisque react-native existe déjà, react.native et reactnative ne peuvent pas être recréés.
Par exemple : le nom d'utilisateur est conard , puis la portée est @conard et le package publié peut être @conard/react .
name est l'identifiant unique d'un package et ne doit pas être répété avec d'autres noms de package. Nous pouvons exécuter npm view packageName pour voir si le package est occupé, et nous pouvons afficher quelques informations de base à ce sujet :

Si le nom du package n'a jamais été utilisé, une erreur 404 sera générée :

De plus, vous pouvez également accéder à https://www.npmjs.com/ pour des informations plus détaillées sur les packages.
{
"description": "Un langage de conception d'interface utilisateur de classe entreprise et une implémentation de composants React",
"mots-clés": [
"fourmi",
"composant",
"composants",
"conception",
"cadre",
"l'extrémité avant",
"réagir",
"composant de réaction",
"ui"
]
} description est utilisé pour ajouter des informations de description du module afin de permettre aux autres de comprendre votre module.
keywords est utilisé pour ajouter des mots-clés à votre module.
Bien entendu, ils jouent également un rôle très important, celui de faciliter la récupération des modules. Lorsque vous utilisez npm search pour récupérer un module, il correspondra description et keywords . La rédaction d'une bonne description et keywords aidera votre module à obtenir une exposition de plus en plus précise :

de décrire les développeurs : author et contributors . author fait référence à l'auteur principal du package, et un author correspond à une personne. contributors font référence aux informations du contributeur. Un contributors correspond à plusieurs contributeurs. La valeur est un tableau. La description de la personne peut être une chaîne ou la structure suivante
:
"name" : "ConardLi",
"email" : "[email protected]",
"url" : "https://github.com/ConardLi"
} {
"homepage": "http://ant.design/",
"insectes": {
"url": "https://github.com/ant-design/ant-design/issues"
},
"dépôt": {
"type": "git",
"url": "https://github.com/ant-design/ant-design"
},
} homepage est utilisé pour spécifier la page d'accueil de ce module.
repository est utilisé pour spécifier le référentiel de code du module.

bugs spécifie une adresse ou un e-mail auquel les personnes qui ont des questions sur votre module peuvent se rendre ici pour poser des questions.
Notre projet peut dépendre d'un ou plusieurs packages de dépendances externes. Selon les différentes utilisations des packages de dépendances, nous les configurons sous les attributs suivants : dependencies、devDependencies、peerDependencies、bundledDependencies、optionalDependencies .
Avant d'introduire plusieurs configurations de dépendances, examinons d'abord les règles de configuration des dépendances. La configuration du package de dépendances que vous voyez peut être la suivante :
"dependencies": {
"antd": "ant-design/ant-design#4.0.0-alpha.8",
"axios": "^1.2.0",
"test-js": "fichier:../test",
"test2-js": "http://cdn.com/test2-js.tar.gz",
"core-js": "^1.1.5",
} La configuration des dépendances suit les règles de configuration suivantes :
依赖包名称:VERSION VERSION est une configuration de numéro de version qui suit SemVer . Lors de npm install il ira sur le serveur npm pour télécharger les packages qui répondent à la plage de versions spécifiée.依赖包名称:DWONLOAD_URL DWONLOAD_URL est une adresse de package compressé tarball téléchargeable. Lorsque le module est installé, ce .tar sera téléchargé et installé localement.依赖包名称:LOCAL_PATH LOCAL_PATH est un chemin de package de dépendances local, tel que file:../pacakges/pkgName . Adaptée pour tester un package npm localement, cette méthode ne doit pas être appliquée en ligne.依赖包名称:GITHUB_URL GITHUB_URL est la méthode d'écriture du username/modulename du module github , par exemple : ant-design/ant-design . Vous pouvez également spécifier tag et commit id ultérieurement.依赖包名称:GIT_URL GIT_URL est git url de notre base de code de clonage habituelle, qui suit la forme suivante :<protocol>://[<user>[:<password>]@]<hostname>[:<port>] [: ][/]<path>[#<commit-ish> | #semver:<semver>]
protocal peut se présenter sous les formes suivantes :
git://github.com/user/project.git#commit-ishgit+ssh://user@hostname:project.git#commit-ishgit+ssh://user@hostname/project.git#commit-ishgit+http://user@hostname/project/blah.git#commit-ishgit+https://user@hostname/project/blah.git#commit-ishdependencies spécifient les modules dont dépend le projet. Les modules de dépendance de l'environnement de développement et de l'environnement de production peuvent être configurés ici, tels que
". dépendances": {
"lodash": "^4.17.13",
"moment": "^2.24.0",
} Il existe certains packages dans que vous ne pouvez utiliser que dans l'environnement de développement, tels que eslint pour vérifier les spécifications du code et jest pour les tests. Lorsque les utilisateurs utilisent votre package, il peut s'exécuter normalement même sans installer ces dépendances, au contraire. cela prendra plus de temps et de ressources, vous pouvez donc ajouter ces dépendances à devDependencies . Ces dépendances seront toujours installées et gérées lorsque vous effectuerez npm install localement, mais ne seront pas installées dans l'environnement de production :
"devDependencies" : {
"je plaisante": "^24.3.1",
"eslint": "^6.1.0",
} peerDependencies sont utilisées pour spécifier la version dont dépend le module que vous développez et la compatibilité de la version du package dépendant installée par l'utilisateur.
L'instruction ci-dessus est peut-être un peu trop abstraite. Prenons ant-design comme exemple. package.json de ant-design a la configuration suivante :
"peerDependencies": {
"réagir": ">=16.0.0",
"react-dom": ">=16.0.0"
} Lorsque vous développez un système et utilisez ant-design , vous devez absolument vous fier à React . Dans le même temps, ant-design doit également s'appuyer sur React . React dont il a besoin pour maintenir un fonctionnement stable est 16.0.0 , et la version React sur laquelle vous comptez lors du développement est 15.x :
À l'heure actuelle, ant-design doit utiliser React et l'importer :
import * as React from 'react' ; import * as ReactDOM from 'react-dom';
Ce que vous obtenez à ce moment est l'environnement hôte, qui est la version React de votre environnement, ce qui peut causer des problèmes. Dans npm2 , spécifier peerDependencies ci-dessus signifiera forcer l'environnement hôte à installer les versions de react@>=16.0.0和react-dom@>=16.0.0 .
À l'avenir, npm3 n'exigera plus que les packages de dépendances spécifiés par peerDependencies soient installés de force. Au contraire npm3 vérifiera si l'installation est correcte une fois l'installation terminée. Si elle est incorrecte, un avertissement sera imprimé à l'utilisateur. .
"dépendances": {
"réagir": "15.6.0",
"antd": "^3.22.0"
} Par exemple, je m'appuie sur la dernière version d' antd dans le projet, puis sur la version 15.6.0 de react . L'avertissement suivant sera donné lors de l'installation de la dépendance :

Dans certains scénarios, le package dépendant peut ne pas être une dépendance forte. La fonction de ce package dépendant est inutile. Lorsque ce package dépendant ne peut pas être obtenu, vous souhaitez que npm install continue de s'exécuter sans provoquer d'échec. optionalDependencies . Notez que la configuration dans optionalDependencies remplacera dependencies elle ne doit donc être configurée qu'à un seul endroit.
Bien entendu, lors du référencement des dépendances installées dans optionalDependencies , une gestion des exceptions doit être effectuée, sinon une erreur sera signalée lorsque le module ne peut pas être obtenu.
est différent de ce qui précède. La valeur de bundledDependencies est un tableau. Certains modules peuvent être spécifiés dans le tableau. Ces modules seront regroupés ensemble lors de la sortie de ce package.
"bundledDependencies": ["package1" , "package2"]
{
"licence": "MIT"
} Le champ license est utilisé pour spécifier l'accord open source du logiciel. L'accord open source détaille les droits dont disposent les autres après avoir obtenu votre code, les opérations qu'ils peuvent effectuer sur votre code et les opérations interdites. Il existe de nombreuses variantes d'un même accord. Un accord trop lâche fera perdre à l'auteur de nombreux droits sur l'œuvre, tandis qu'un accord trop strict ne facilitera pas l'utilisation et la diffusion de l'œuvre. , les auteurs open source doivent réfléchir aux droits qu'ils souhaitent conserver et aux restrictions qu'ils souhaitent assouplir.
Les contrats de logiciels peuvent être divisés en deux catégories : open source et commerciaux. Pour les accords commerciaux, également appelés déclarations juridiques et contrats de licence, chaque logiciel aura son propre ensemble de textes, rédigés par l'auteur du logiciel ou un avocat spécialisé. il n'est pas nécessaire de le faire vous-même. Consacrez du temps et des efforts à la rédaction de longs contrats de licence. Choisir une licence open source largement diffusée est un bon choix.
Voici plusieurs protocoles open source courants :

MIT : Tant que les utilisateurs incluent une mention de copyright et une mention de licence dans leurs copies du projet, ils peuvent faire ce qu'ils veulent avec votre code sans aucune responsabilité de votre part.Apache : similaire au MIT , mais inclut également des termes liés aux licences de brevet fournies par les contributeurs aux utilisateurs.GPL : Les utilisateurs qui modifient le code du projet doivent publier leurs modifications pertinentes lors de la redistribution du code source ou du code binaire.Si vous avez des exigences plus détaillées pour l'accord open source, vous pouvez accéder à Choosealicense.com/ pour une description plus détaillée de l'accord open source.

{
"main": "lib/index.js",
} L'attribut main peut spécifier le fichier d'entrée principal du programme. Par exemple, l'entrée du module lib/index.js spécifiée par antd ci-dessus antd import { notification } from 'antd'; ce qui est introduit, ce sont lib/index.js .

Lorsque votre module est un outil de ligne de commande, vous devez spécifier une entrée pour l'outil de ligne de commande, c'est-à-dire spécifier la correspondance entre le nom de votre commande et le fichier local spécifiable. S'il est installé globalement, npm utilisera un lien symbolique pour lier le fichier exécutable à /usr/local/bin . S'il est installé localement, il sera lié à ./node_modules/.bin/ .
{
"poubelle": {
"conard": "./bin/index.js"
}
} Par exemple, la configuration ci-dessus : Lorsque votre package est installé globalement : npm créera un lien symbolique nommé conard sous /usr/local/bin , pointant vers "./bin/index.js" . À ce stade, si vous exécutez conard sur la ligne de commande, le fichier js lié sera appelé.
Je n'entrerai pas dans les détails ici, plus de contenu sera expliqué en détail dans mes prochains articles sur les outils de ligne de commande.
{
"fichiers": [
"dist",
"lib",
"es"
]
} L'attribut files est utilisé pour décrire la liste des fichiers que vous transmettez au serveur npm après npm publish . Si vous spécifiez un dossier, tout le contenu du dossier sera inclus. Nous pouvons voir que le package téléchargé a la structure de répertoires suivante :

De plus, vous pouvez également configurer un fichier
.npmignorepour exclure certains fichiers afin d'éviter qu'un grand nombre de fichiers indésirables ne soient transmis ànpm. Les règles sont les mêmes que.gitignoreque vous utilisez. Les fichiers.gitignorepeuvent également agir comme des fichiers.npmignore.
La commande man est une commande d'aide sous Linux . Grâce à la commande man , vous pouvez afficher l'aide sur les commandes, l'aide sur les fichiers de configuration, l'aide sur la programmation et d'autres informations sous Linux .
Si votre module node.js est un outil de ligne de commande global, vous pouvez spécifier l'adresse du document recherchée par la commande man via l'attribut man dans package.json .
Les fichiers man doivent se terminer par un nombre ou, s'ils sont compressés, .gz . Le numéro indique dans quelle partie de man le fichier sera installé. Si le nom du fichier man ne commence pas par le nom du module, le nom du module sera préfixé lors de l'installation.
Par exemple, la configuration suivante :
{
"homme" : [
"/Users/isaacs/dev/npm/cli/man/man1/npm-access.1",
"/Users/isaacs/dev/npm/cli/man/man1/npm-audit.1"
]
} Entrez man npm-audit sur la ligne de commande :

Un module node.js est implémenté sur la base de CommonJS . En stricte conformité avec la spécification CommonJS , en plus du fichier de description du package package.json , le répertoire du module doit également contenir les répertoires suivants :
bin : où. les fichiers binaires exécutables sont stockés. Répertoirelib : Répertoire de stockage du code jsdoc : Répertoire de stockage des documentstest : Répertoire de stockage du code du scénario de test unitaireDans le répertoire du module, vous ne pouvez pas suivre strictement la structure ci-dessus pour l'organiser ou le nommer. . Vous pouvez spécifier directories dans les propriétés package.json pour spécifier comment votre structure de répertoires correspond à la structure canonique ci-dessus. En dehors de cela, l’attribut directories n’a pour l’instant aucune autre application.
{
"répertoires": {
"lib": "src/lib/",
"bin": "src/bin/",
"homme": "src/homme/",
"doc": "src/doc/",
"exemple": "src/exemple/"
}
} Cependant, le document officiel indique que même si cet attribut n'a actuellement aucun rôle important, certaines astuces pourraient être développées à l'avenir. Par exemple, les fichiers markdown stockés dans doc et les fichiers d'exemple stockés dans example peuvent être affichés de manière conviviale.
{
"scripts": {
"test": "jest --config .jest.js --no-cache",
"dist": "antd-tools exécute dist",
"compile": "antd-tools exécute la compilation",
"build": "npm run compile && npm run dist"
}
} scripts sont utilisés pour configurer les abréviations de certaines commandes de script. Chaque script peut être utilisé en combinaison les uns avec les autres. Ces scripts peuvent couvrir l'ensemble du cycle de vie du projet, ils peuvent être appelés à l'aide npm run command . S'il s'agit d'un mot-clé npm , il peut être appelé directement. Par exemple, la configuration ci-dessus spécifie les commandes suivantes : npm run test , npm run dist , npm run compile , npm run build .
Le champ config est utilisé pour configurer les variables d'environnement utilisées dans le script. Par exemple, la configuration suivante peut être obtenue en utilisant process.env.npm_package_config_port dans le script.
{
"config" : { "port" : "8080" }
} Si votre module node.js est principalement utilisé pour installer des outils de ligne de commande globaux, alors cette valeur est définie sur true et les utilisateurs recevront un avertissement lorsqu'ils installeront le module localement. Cette configuration n'empêchera pas les utilisateurs d'installer, mais les invitera à éviter une utilisation incorrecte pouvant entraîner certains problèmes.
Si l'attribut private est défini sur true , npm refusera de le publier afin d'éviter qu'un module privé soit publié accidentellement.

"publierConfig": {
"registre": "https://registry.npmjs.org/"
}, configuration plus détaillée lors de la publication du module, par exemple, vous pouvez configurer pour publier uniquement une certaine tag , configurer la source npm privée sur laquelle publier.
une configuration plus détaillée, veuillez vous référer à npm-config
Si vous développez un module qui ne peut fonctionner que sous le système darwin , vous devez vous assurer que les utilisateurs windows n'installeront pas votre module pour éviter des erreurs inutiles.
L'utilisation de l'attribut os peut vous aider à remplir les conditions ci-dessus. Vous pouvez spécifier que votre module ne peut être installé que sur certains systèmes, ou spécifier une liste noire de systèmes qui ne peuvent pas être installés :
"os" : [ "darwin", "linux" ] "os" : [ "!win32" ]
Par exemple, j'attribue un module de test à une liste noire du système : "os" : [ "!darwin" ] Lorsque je l'installe sous ce système, l'erreur suivante apparaîtra :

Dans l'environnement de nœud, vous pouvez utiliser process.platform pour déterminer le système d'exploitation.
est similaire au os ci-dessus. Nous pouvons utiliser l'attribut cpu pour limiter plus précisément l'environnement d'installation de l'utilisateur :
"cpu" : [ "x64", "ia32" ] "cpu" : [ "!arm", "!mips" ]
Dans l'environnement de nœud, vous pouvez utiliser process.arch pour déterminer l'architecture du processeur.
Le succès de Nodejs est indissociable de l'excellent système de gestion des dépendances de npm . Avant de présenter l'ensemble du système de dépendances, vous devez comprendre comment npm gère les versions des packages dépendants. Ce chapitre présentera les spécifications de version des npm包, comment gérer les versions de divers packages dépendants et quelques bonnes pratiques concernant les versions des packages.

Vous pouvez exécuter npm view package version pour afficher la dernière version d'un package .
Exécutez npm view conard versions pour afficher toutes les versions publiées d'un package sur le serveur npm.

Exécutez npm ls pour afficher les informations de version de tous les packages dans l'arborescence de dépendances de l'entrepôt actuelle.

Les versions de module dans npm包doivent suivre SemVer - une règle directrice et unifiée de représentation du numéro de version rédigée par Github . C'est en fait l'abréviation de Semantic Version .
Site officiel de la spécification SemVer : https://semver.org/Standard
Le numéro de version standard de SemVer adopte le format XYZ , où X, Y et Z sont des entiers non négatifs, et un remplissage nul devant les nombres est interdit. X est le numéro de version majeure, Y est le numéro de version mineure et Z est le numéro de révision. Chaque élément doit être incrémenté numériquement.
major ) : Lorsque vous effectuez des modifications d'API incompatiblesminor ) : Lorsque vous effectuez des fonctionnalités rétrocompatibles Nouveaupatch ) : Lorsque vous effectuez des problèmes de compatibilité ascendante Correction.Par exemple : 1.9.1 -> 1.10.0 -> 1.11.0
Lorsqu'une version présente des modifications majeures, n'est pas stable et peut ne pas répondre aux exigences de compatibilité attendues, vous souhaiterez peut-être d'abord publier une version avancée.
Le numéro de version principal peut être ajouté à la fin de "numéro de version majeure. numéro de version mineure. numéro de révision". Ajoutez d'abord un numéro de connexion, puis une série d'identifiants et d'informations de compilation de version séparés par des points.
alpha ) :beta ) :rc : Release candiateJetons un coup d'œil aux versions historiques de React :

On peut voir que la version est publiée strictement conformément à SemVer :
主版本号.次版本号.修订号La16.8.0 -> 16.8.1 -> 16.8.2alpha , beta , rc et autres versions avancées. Après avoir modifié certaines fonctions du paquet npm , il est généralement nécessaire de publier un . nouvelle version. Notre approche habituelle consiste à modifier directement package.json vers la version spécifiée. Si l'opération est incorrecte, il est facile de créer une confusion dans le numéro de version. On peut utiliser des commandes conformes à Semver pour réaliser cette opération :
npm version patch : mettre à jour le numéro de révisionnpm version minor : mettre à jour le numéro de version mineurenpm version major : mettre à jour le numéro de version majeureen développement est définitivement indispensable pour le fonctionnement de certains numéros de version Si ces numéros de version sont conformes à la spécification SemVer , nous pouvons utiliser le package npm semver pour exploiter les versions pour nous aider. comparer les tailles de version, extraire les informations de version et d’autres opérations.
Npm utilise également cet outil pour gérer le travail de versionnage.
npm install semver
semver.gt('1.2.3', '9.8.7') // false
semver.lt('1.2.3', '9.8.7') // true semver.valid('1.2.3') // '1.2.3'
semver.valid('abc') // null semver.valid(semver.coerce('v2')) // '2.0.0'
semver.valid(semver.coerce('42.6.7.9.3-alpha')) // semver.clean(' =v1.2.3 ') // '1.2.3'
semver.satisfies('1.2.3', '1.x || >=2.5.0 || 5.0.0 - 7.2.3') // vrai
semver.minVersion('>=1.0.0') // '1.0.0' Voici les utilisations les plus courantes de semver. Pour plus de détails, veuillez consulter la documentation de semver : https://github.com/npm/node. -semver
Nous voyons souvent différentes manières d'écrire diverses dépendances dans package.json :
"dependencies": {
"signal": "1.4.0",
"figlet": "*",
"réagir": "16.x",
"table": "~5.4.6",
"yargs": "^14.0.0"
} Les trois premiers sont faciles à comprendre :
"signale": "1.4.0" : Numéro de version fixe"figlet": "*" : N'importe quelle version ( >=0.0.0 )"react": "16.x" : Correspondance Version principale ( >=16.0.0 <17.0.0 )"react": "16.3.x" : Faire correspondre la version majeure et la version mineure ( >=16.3.0 <16.4.0 )Jetons un coup d'œil aux deux dernières, la numéro de version Les symboles ~ et ^ sont cités :
~ : Lorsqu'une nouvelle version est obtenue lors de l'installation des dépendances, installez la dernière version de z dans xyz . Autrement dit, tout en gardant inchangés le numéro de version majeure et le numéro de version mineure, le numéro de révision la plus récente est conservé.^ : Lorsqu'une nouvelle version est obtenue lors de l'installation des dépendances, y et z dans xyz installés sont les dernières versions. Autrement dit, tout en conservant le numéro de version majeure inchangé, conservez le numéro de version mineure et le numéro de révision comme dernière version.La dépendance la plus courante dans le fichier package.json devrait être "yargs": "^14.0.0" , car lorsque nous utilisons npm install package pour installer le package, npm installe la dernière version par défaut, puis l'installe dans le fichier Ajouter. un signe ^ avant le numéro de version.
Notez que lorsque le numéro de version majeure est 0 , elle sera considérée comme une version instable. La situation est différente de celle ci-dessus :
0 : ^0.0.z et ~0.0.z sont tous deux. considérées comme des versions fixes, aucun changement ne se produira lors de l’installation des dépendances.0 : ^0.yz se comporte de la même manière que ~0.yz , seul le numéro de révision est conservé comme dernière version.Le numéro de version 1.0.0 est utilisé pour définir l'API publique. Lorsque votre logiciel est publié dans l'environnement officiel ou dispose d'une API stable, vous pouvez publier la version 1.0.0. Ainsi, lorsque vous décidez de publier une version officielle d'un package npm dans le monde extérieur, marquez sa version comme 1.0.0.
Dans le développement réel, des problèmes étranges se produisent souvent en raison d'incohérences dans diverses dépendances, ou dans certains scénarios, nous ne voulons pas que les dépendances soient mises à jour. Il est recommandé d'utiliser package-lock.json pendant le développement.
Le verrouillage de la version de la dépendance signifie qu'à moins que nous effectuions des mises à jour manuellement, la version corrigée sera installée à chaque fois que nous installerons la dépendance. Assurez-vous que toute l’équipe utilise des dépendances avec des numéros de version cohérents.
Chaque fois que vous installez une version fixe, il n'est pas nécessaire de calculer la plage de versions de dépendance, ce qui peut considérablement accélérer le temps d'installation des dépendances dans la plupart des scénarios.
Lorsque vous utilisez package-lock.json, assurez-vous que la version de npm est supérieure à 5.6, car entre 5.0 et 5.6, la logique de traitement de package-lock.json a été mise à jour plusieurs fois et la logique de post-traitement de la version 5.6 s'est progressivement stabilisée.
Nous analyserons la structure détaillée de package-lock.json dans les chapitres suivants.
Notre objectif
Dans les scénarios de développement réels, même si nous n'avons pas besoin d'installer une nouvelle version à chaque fois, nous devons toujours mettre à jour régulièrement les versions de dépendances afin de pouvoir profiter des correctifs de problèmes, des améliorations de performances et des nouvelles mises à jour de fonctionnalités apportées par les mises à niveau des packages de dépendances.

L'utilisation de npm outdated peut nous aider à répertorier les dépendances qui n'ont pas été mises à niveau vers la dernière version :
et exécuter npm update . Mettez à niveau toutes les dépendances rouges.
1.0.0 .主版本号.次版本号.修订号alpha、beta、rc et. D'abord,npm développés par les membres de l'équipe. À l'heure actuelle, il est recommandé de changer le préfixe de version ~ . Les dépendances du projet principal doivent être mises à niveau à chaque fois que les sous-dépendances sont mises à jour, ce qui est très fastidieux. Si les sous-dépendances sont entièrement fiables, ouvrez-les directement ^ Mettez à niveau vers la dernière version à chaque fois.docker et les sous-dépendances sont toujours en cours de développement et de mise à niveau localement. Avant la publication de la version docker , toutes les versions de dépendances doivent être verrouillées pour garantir qu'il n'y aura aucun problème en ligne après la mise en ligne des sous-dépendances locales. libéré.npm est supérieure à 5.6 et assurez-vous que le fichier package-lock.json est activé par défaut.npm inatall exécuté par le membre d'initialisation, package-lock.json est soumis à l'entrepôt distant. Ne soumettez pas node_modules directement au référentiel distant.npm update pour mettre à niveau les dépendances et soumettez le fichier lock pour vous assurer que les autres membres mettent à jour leurs dépendances simultanément. Ne modifiez pas le fichier lock manuellement.package.json et exécutez npm installlocknpm install package@version (la modification de package.json ne rétrogradera pas les dépendances).
npm install passera probablement par les processus ci-dessus. Ce chapitre parlera des détails d'implémentation, du développement et du pourquoi de chaque processus.
Nous savons tous qu'après l'exécution npm install , les packages dépendants sont installés dans node_modules . Examinons de plus près le mécanisme spécifique par lequel npm installe les packages dépendants dans node_modules .
Dans les premières versions de npm , la manière dont npm gérait les dépendances était simple et grossière. Il installait les dépendances dans leurs node_modules respectifs de manière récursive et strictement selon la structure package.json et la structure package.json des packages de sous-dépendances. Jusqu'à ce qu'il existe des packages sous-dépendants qui ne dépendent plus des autres modules.
Par exemple, notre module my-app dépend désormais de deux modules : buffer et ignore :
{
"name": "mon-application",
"dépendances": {
"tampon": "^5.4.3",
"ignorer": "^5.1.4",
}
} ignore est un module JS pur qui ne dépend d'aucun autre module, et buffer dépend des deux modules suivants : base64-js et ieee754 .
{
"name": "tampon",
"dépendances": {
"base64-js": "^1.0.2",
"ieee754": "^1.1.4"
}
} Ensuite, après avoir exécuté npm install , la structure du répertoire du module dans node_modules obtenue est la suivante :

Les avantages de cette approche sont évidents. La structure de node_modules correspond à la structure de package.json un à un, la structure hiérarchique est évidente et la structure des répertoires de chaque installation est garantie d'être la même.
Cependant, imaginez, si vous dépendez de beaucoup de modules, vos node_modules seront très volumineux et le niveau d'imbrication sera très profond :

Windows , la longueur maximale du chemin d'accès au fichier est de 260 caractères et un niveau d'imbrication trop profond peut entraîner des problèmes imprévisibles.Afin de résoudre les problèmes ci-dessus, NPM a effectué une mise à jour majeure dans la version 3.x Il transforme la première structure imbriquée en une structure plate :
node_modules .Toujours avec la structure de dépendances ci-dessus, nous obtiendrons la structure de répertoires suivante après avoir exécuté npm install :


À l'heure actuelle, si nous comptons sur la version [email protected] dans le module:
{
"nom": "my-app",
"dépendances": {
"tampon": "^ 5.4.3",
"ignorer": "^ 5.1.4",
"base64-js": "1.0.1",
}
} node_modulesÀ ce stade, nous obtiendrons la structure du répertoire suivant après avoir exécuté npm install :


En conséquence, si nous référons un module dans le code de projet, le processus de recherche du module est le suivant:
node_modulesnode_modulesnode_modules[email protected] buffer2@^5.4.3

Par conséquent, la version npm 3.x ne résout pas complètement le problème de redondance du module de l'ancienne version et peut même apporter de nouveaux problèmes.
Imaginez que votre application ne dépend pas de la version [email protected] , mais vous dépendez également de buffer et buffer2 qui dépendent de différentes versions base64-js . Depuis lors de l'exécution de npm install , les dépendances dans package.json sont analysées dans l'ordre, l'ordre dans lequel buffer et buffer2 sont placés dans package.json détermine la structure de dépendance de node_modules :
Dépensez à buffer2 d'abord:

Dépendent d'abord buffer :

De plus, afin de permettre aux développeurs d'utiliser les derniers packages de dépendance sous la prémisse de la sécurité, nous ne verrouillons généralement que la grande version dans package.json , ce qui signifie qu'après la mise à jour de la version mineure être également modifié.
Afin de résoudre le problème d'incertitude de npm install , le fichier package-lock.json a été ajouté dans la version npm 5.x , et la méthode d'installation suit également la méthode plate de npm 3.x
La fonction de package-lock.json package-lock.json npm install verrouiller la structure de node_modules . .
Par exemple, nous avons la structure de dépendance suivante:
{
"nom": "my-app",
"dépendances": {
"tampon": "^ 5.4.3",
"ignorer": "^ 5.1.4",
"base64-js": "1.0.1",
}
} package-lock.json généré après l'exécution npm install est le suivant:
{
"nom": "my-app",
"version": "1.0.0",
"dépendances": {
"base64-js": {
"Version": "1.0.1",
"Resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
"Intégrité": "sha1-asbrszt7xze47tutdw3i / np + pag ="
},
"tampon": {
"Version": "5.4.3",
"Resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
"Intégrité": "sha512-zvj65tkfeit3i6aj5Bivjdzjjjqgs4o / snoEZg1f1kyap9nu2jcudpwzrsjthmmzg0h7bzkn4rnqpimhuxwx2a ==",
"Nécessite": {
"base64-js": "^ 1.0.2",
"IEEE754": "^ 1.1.4"
},
"dépendances": {
"base64-js": {
"Version": "1.3.1",
"Resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"Integrity": "sha512-mlq4i2qo1ytvgwfwmcngko // jxaquezvwektjgqfm4jik0ku + ytmfpll8j + n5mspofjhwoag + 9yhb7bwahm36g =="
}
}
},
"IEEE754": {
"Version": "1.1.13",
"Resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
"Integrity": "sha512-4vf7i2lyv / hawnerso3xmlmkp5ez83i + / cdluxi / igts / o1sejbnhttnxzmrzfvouqj7lzjqhketvpgsfdlwztg =="
},
"ignorer": {
"Version": "5.1.4",
"Resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
"Intégrité": "sha512-mzbusahktw1u7jpkkjy7lcard1fu5w2rldxlm4kdkayucwzimjkpluf9cm1alewyjgupdqewlam18y6au69a8a =="
}
}
} Examinons de plus près la structure ci-dessus:

Les deux attributs les plus extérieurs name et version sont les mêmes que name et version dans package.json , et sont utilisés pour décrire le nom et la version actuels du package.
dependencies sont key objet qui correspond à la structure du node_modules
resolvedversion node_modulesdependencies requiresintegrity hash Subresource Integrity modifié ou invalide.package.json dépendance.json.dependencies : La structure est la même que la structure dependencies extérieures et stocke les packages de dépendance installés dans la sous-dépendance node_modules .Notez ici que toutes les sous-dépendances n'ont pas l'attribut dependencies node_modules
Par exemple, passez en revue les dépendances ci-dessus:

La version [email protected] sur laquelle nous nous appuyons dans les conflits my-app avec base64-js@^1.0.2 sur lesquels nous comptons dans buffer , donc [email protected] doit être installé dans node_modules de la Le package buffer , correspondant à l'attribut de dependencies du buffer dans package-lock.json a été modifié. Cela correspond également à l'approche plate de npm aux dépendances.
Par conséquent, selon l'analyse ci-dessus, package-lock.json package-lock.json node_modules sont en correspondance individuelle. généré par chaque installation identique.
De plus, l'utilisation de package-lock.json dans le projet peut accélérer considérablement le temps d'installation de dépendance.
lock utilisons le npm i --timing=true --loglevel=verbose lock pour voir le processus complet de npm install . Nettoyez le cache npm avant de comparer.
Sans utiliser le fichier lock :

Utilisez le fichier lock :

On peut voir que la version spécifique et le lien de téléchargement de chaque package ont été mis en cache dans package-lock.json . Grand nombre de demandes de réseau.
pour développer des applications système, il est recommandé de soumettre le fichier package-lock.json au référentiel de versions de code pour s'assurer que les versions de dépendance installées par tous les développeurs d'équipes et les liens CI sont cohérents lors de l'exécution npm install .
Lors du développement semver un package npm , votre package npm doit être dépendant des autres référentiels. Dans le cadre, ce qui entraînera une redondance inutile. Nous ne devons donc pas publier le fichier package-lock.json ( npm ne publiera pas package-lock.json par défaut).
après avoir exécuté la commande npm install ou npm update pour télécharger les dépendances, en plus d'installer le package de dépendance dans le répertoire node_modules , une copie sera également mise en cache dans le répertoire de cache local.
Vous pouvez l'interroger via npm config get cache : Dans Linux ou Mac la valeur par défaut est le répertoire .npm/_cacache dans le répertoire personnel de l'utilisateur.
tar y a deux répertoires dans ce répertoire hash content-v2 content-v2 tar index-v5 index-v5
Lorsque NPM exécute l'installation, il peut générer une key unique correspondant à l'enregistrement de cache dans le répertoire index-v5 en fonction de integrity、version、name stocké dans package-lock.json , trouvant ainsi hash du package tar , Et tar le rechercher sur la base hash .
Nous pouvons trouver un package pour rechercher et tester dans le répertoire de cache, et rechercher le chemin du package dans index-v5 :
grep "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1. tgz "-r index-v5

Ensuite, nous formations le JSON:
{
"Key": "Pacote: Version-Manifest: https: //registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz: sha1-asbrszt7xze47tutdw3i / np + pag =",
"Intégrité": "sha512-c2ekhxwxvlsbrucjtrs3xfhv7mf / y9klmkdxpte8yevcoh5h8ae69y + / lp + ahpw91crnzgo78elok2e6apjfiq ==",,
"Temps": 1575554308857,
"taille": 1,
"métadonnées": {
"id": "[email protected]",
"manifeste": {
"nom": "base64-js",
"Version": "1.0.1",
"moteurs": {
"nœud": "> = 0,4"
},
"dépendances": {},
"OptionAldependences": {},
"DevDependces": {
"Standard": "^ 5.2.2",
"bande": "4.x"
},
"BundledEpendeces": FALSE,
"PeerDependances": {},
"déprécié": faux,
"_resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
"_integrity": "sha1-asbrszt7xze47tutdw3i / np + pag =",
"_shasum": "6926d1b194fbc737b8eed513756de2fcda7ea408",
"_shrinkwrap": null,
"bin": null,
"_id": "[email protected]"
},
"Type": "Finalisation-Manifest"
}
} L'attribut _shasum ci-dessus 6926d1b194fbc737b8eed513756de2fcda7ea408 est hash du package tar , et les premiers digits 6926 du hash sont les deux premiers niveaux de répertoires cachés.

La stratégie de mise en cache ci-dessus commence à partir de la version NPM V5. }.
npm fournit plusieurs commandes pour gérer les données du cache:
npm cache add : L'explication officielle est que cette commande est principalement utilisée en interne par npm , mais elle peut également être utilisée pour ajouter manuellement un cache à un package spécifié.npm cache clean --force supprimez toutes les données du répertoire de cache.npm cache verify : Vérifiez la validité et l'intégrité des données mises en cache et nettoyez les données indésirables.Sur la base de données en cache, NPM fournit des modes d'installation hors ligne, qui sont les suivants:
--prefer-offline : Utilisez d'abord des données mises en cache.--prefer-online : hiérarchisez l'utilisation des données du réseau.--offline : ne demandez pas le réseau et utilisez directement les données en cache.Nous avons mentionné l'intégrité des fichiers plusieurs fois ci-dessus, alors qu'est-ce que la vérification de l'intégrité du fichier?
tarball de télécharger le shasum de dépendance, nous pouvons généralement obtenir hash hash par npm npm info le package de dépendance.

Une hash que l'utilisateur télécharge localement le package de dépendance, il doit s'assurer hash erreur s'est produite pendant le processus de téléchargement. Sont les mêmes, assurez-vous que la dépendance téléchargée est terminée.
Maintenant que le processus global est terminé, résumons le processus ci-dessus:
.npmrc .npmrc fichier .npmrc : la priorité est: Fichier .npmrc au niveau du projet Fichier .npmrc
Vérifiez s'il y a un fichier lock dans le projet.
Aucun fichier lock :
npmpackage.json . node_modules .node_modules du module actuel.npm le package de téléchargement d'entrepôt distantnpmnode_modules en fonction de la structure de dépendancelocknode_modulesnode_modules de la structurelock
package-lock.json package.json package-lock.json .
Le processus ci-dessus décrit brièvement le processus général de npm install npm install package --timing=true --loglevel=verbose Processus d'installation et détails d'un certain package.

yarn a été publié en 2016 À ce moment package-lock.json là, npm était toujours dans V3 . des développeurs. À ce stade, yarn est né:

Ce qui précède sont les avantages du yarn mentionné sur le site officiel, qui étaient encore très attrayants à ce moment-là. Bien sûr, npm a réalisé yarn lock problèmes yarn a fait de nombreuses optimisations. Le design est toujours très bon.
de
yarn yarn.lock npm v3 gérer les yarn.lock .
Est un fichier automatique. # Yarn LockFile V1 [email protected]: Version "1.0.1" Résolu "https://registry.yarnpkg.com/base64-js/-/base64-js-1.0.1.tgz#6926d1b194fbc737b8eed513756de2fcda7ea408" intégrité sha1-asbrszt7xze47tutdw3i / np + pag = base64-js@^1.0.2: Version "1.3.1" résolu "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" Integrity sha512-mlq4i2qo1ytvgwfwmcngko // jxaquezvwektjgqfm4jik0ku + ytmfpll8j + n5mspofjhwoag + 9yhb7bwahm36g == tamper@^5.4.3: Version "5.4.3" résolu "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115" Integrity sha512-zvj65tkfeit3i6aj5bivjdzjjjqgs4o / snoezg1f1kyap9nu2jcudpwzrsjthmmzg0h7bzkn4rnqpimhuxwx2a == dépendances : base64-js "^ 1.0.2" IEEE754 "^ 1.1.4" IEEE754@^1.1.4: Version "1.1.13" Résolu "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" Integrity sha512-4vf7i2lyv / hawnerso3xmlmkp5ez83i + / cdluxi / igts / o1sejbnhttnxzmrzfvouqj7lzjqhketvpgsfdlwztg == ignore@^5.1.4: Version "5.1.4" résolu "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" Integrity sha512-mzbusahktw1u7jpkkjy7lcard1fu5w2rldxlm4kdkayucwzimjkpluf9cm1alewyjgupdqewlam18y6au69a8a
package-lock.json
yarn.lock json package-lock.jsonyarn.lock Le numéro de version de yarn.lock n'est pas fixe, ce qui signifie que yarn.lock seul ne peut pas déterminer node_modules et doit être coordonné avec le fichier package.json . Et package-lock.json n'a besoin que d'un fichier à déterminer.La stratégie de mise en cache de yarn ressemble beaucoup à celle avant npm v5 . Utilisez le yarn cache dir de commande pour afficher le répertoire des données en cache:

Par défaut,
yarnutilise le modeprefer-online, ce qui signifie que les données réseau sont utilisées en premier.
J'espère qu'après avoir lu cet article, cela vous aidera comme suit:
npmpacakge.json pour avoir des informations supplémentaires sur la configuration d'ingénierie du projet.npm npm install package-lock.json