Chaque projet JavaScript commence par de bonnes intentions, Ă savoir que ses crĂ©ateurs se promettent de ne pas utiliser trop de packages NPM lors de son dĂ©veloppement. Mais mĂȘme si les dĂ©veloppeurs font des efforts considĂ©rables pour tenir cette promesse, les packages NPM pĂ©nĂštrent progressivement leurs projets. La taille du fichier package.json
augmente avec le temps. Et avec l' package-lock.json
installation des dĂ©pendances, une vĂ©ritable horreur se produit, exprimĂ©e en ajouts et suppressions de packages, surtout perceptible avec le prochain PR ... "Tout va bien", explique le chef d'Ă©quipe. Le reste de l'Ă©quipe acquiesce d'un signe de tĂȘte. Que faire d'autre? Nous apprĂ©cions tous le fait que l'Ă©cosystĂšme JavaScript est bel et bien vivant. Nous n'avons pas besoin de rĂ©inventer la roue Ă chaque fois et d'essayer de rĂ©soudre les problĂšmes qui ont dĂ©jĂ Ă©tĂ© rĂ©solus par la communautĂ© open source.
Supposons que vous allez créer un blog et que vous souhaitiez utiliser Gatsby.js. Essayez d'ajouter ce générateur de site en fonction de votre projet. Maintenant, félicitations. Votre projet venait d'avoir 19 000 dépendances supplémentaires. C'est normal? Dans quelle mesure un arbre de dépendance JavaScript peut-il devenir complexe? Comment un arbre de dépendance se transforme-t-il en enfer? Voyons cela.Qu'est-ce qu'un package JavaScript?
NPM (Node Package Manager, Node Package Manager) stocke le plus grand registre de packages au monde. Ce sont des packages JavaScript. NPM est plus que RubyGems, PyPi et Maven rĂ©unis. Cette conclusion peut ĂȘtre tirĂ©e sur la base de l'analyse des donnĂ©es du projet Module Counts , qui surveille le nombre de packages dans les registres populaires.DonnĂ©es sur le nombre de packages dans les registres populairesVous pourriez penser que de trĂšs grandes quantitĂ©s de code sont reprĂ©sentĂ©es sur ce graphique. C'est comme ça. Pour transformer un projet en package NPM, ce package doit avoir un fichierpackage.json
. Un tel package peut ĂȘtre envoyĂ© au registre NPM.Qu'est-ce que package.json?
Voici les tùches qu'il résout package.json
:- Il répertorie les packages dont dépend votre projet (il s'agit d'une liste de dépendances de projet).
- Dans ce document, en utilisant les rÚgles de gestion de versions sémantique, les versions des packages de dépendances que votre projet peut utiliser sont définies.
- Il vous permet de reproduire l'environnement nécessaire au fonctionnement du package et, par conséquent, simplifie le transfert du projet à d'autres développeurs.
Un fichier package.json
peut ĂȘtre considĂ©rĂ© comme un fichier README
pompĂ© de stĂ©roĂŻdes. Ici, vous pouvez dĂ©crire les dĂ©pendances de votre package, ici vous pouvez Ă©crire des scripts qui sont exĂ©cutĂ©s pendant l'assemblage et le test du projet. Le mĂȘme fichier contient des informations sur la version du projet spĂ©cifiĂ©e par son dĂ©veloppeur et une description du projet. Nous sommes particuliĂšrement intĂ©ressĂ©s par la possibilitĂ© package.json
de spĂ©cifier les dĂ©pendances du projet.Peut-ĂȘtre que le fait que les dĂ©pendances du projet soient indiquĂ©es dans ce fichier semble quelque peu alarmant. Imaginez qu'il existe un package qui dĂ©pend d'un autre package, et cet autre package dĂ©pend d'un autre package. Une telle chaĂźne de dĂ©pendances peut ĂȘtre arbitrairement longue. Pour cette raison, l'installation du seul package, Gatsby.js, signifie Ă©quiper le projet de 19 000 dĂ©pendances supplĂ©mentaires.Types de dĂ©pendances dans package.json
Afin de mieux comprendre comment les listes de dépendances de projet augmentent au fil du temps, parlons des différents types de dépendances qu'un projet peut avoir. A savoir, les package.json
sections suivantes peuvent ĂȘtre trouvĂ©es qui dĂ©crivent diverses dĂ©pendances:dependencies
- ce sont des dépendances ordinaires, dont la fonctionnalité est utilisée dans le projet, et qui sont accessibles à partir de son code.devDependencies
- ce sont des dépendances de développement. Par exemple, la plus jolie bibliothÚque utilisée pour formater le code.peerDependencies
- si des dépendances sont écrites dans cette section, le développeur du package informe ainsi celui qui va l'installer qu'il aura besoin d'une version spécifique du package spécifiée dans cette section.optionalDependencies
- ils listent les dépendances optionnelles, telles que l'impossibilité d'installation qui ne violera pas le processus d'installation du package.bundledDependencies
â , . , NPM, , .
package-lock.json
Nous savons tous que le dossier package-lock.json
, au cours des travaux sur le projet, subit constamment des modifications. Quelque chose en est supprimé, quelque chose y est ajouté. Cela est particuliÚrement visible lorsque vous visualisez PR contenant une version mise à jour de ce fichier. Nous le tenons souvent pour acquis. Un fichier est package-lock.json
généré automatiquement chaque fois qu'un fichier package.json
ou un dossier change node_modules
. Cela vous permet de conserver le contenu de l'arborescence de dĂ©pendances exactement tel qu'il Ă©tait lorsque vous avez installĂ© les dĂ©pendances du projet. Cela permet, lors de l'installation du projet, de reproduire l'arborescence des dĂ©pendances. Cela rĂ©sout le problĂšme d'avoir diffĂ©rentes versions du mĂȘme package de diffĂ©rents dĂ©veloppeurs.Prenons un projet dont les dĂ©pendances incluent React. L'entrĂ©e correspondante est disponible sur package.json
. Si vous regardez le fichierpackage-lock.json
de ce projet, vous pouvez voir quelque chose comme ceci: "react": {
"version": "16.13.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.13.0.tgz",
"integrity": "sha512-TSavZz2iSLkq5/oiE7gnFzmURKZMltmi193rm5HEoUDAXpzT9Kzw6oNZnGoai/4+fUnm7FqS5dwgUL34TujcWQ==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2"
}
}
Un fichier package-lock.json
est une grande liste de dépendances de projet. Voici les versions de dépendance, les chemins (URI) vers les modules, les hachages utilisés pour vérifier l'intégrité du module et les packages nécessaires à ce module. Si vous lisez ce fichier, vous pouvez trouver des enregistrements de tous les packages dont React a besoin. C'est là que réside l'enfer des dépendances. Tout ce dont le projet a besoin est décrit ici.Comprendre les dépendances de Gatsby.js
Comment se fait-il qu'ayant établi une seule dépendance, nous ajoutions jusqu'à 19 000 dépendances au projet? Tout dépend des dépendances de dépendance. C'est pourquoi nous avons ce que nous avons:$ npm install --save gatsby
...
+ gatsby@2.19.28
added 1 package from 1 contributor, removed 9 packages, updated 10 packages and audited 19001 packages in 40.382s
Si vous regardez package.json
dedans, vous ne pouvez trouver qu'une seule dépendance. Mais si vous le regardez package-lock.json
, il s'avÚre que devant nous se trouve un monstre de presque 14 kilo-octets. Une réponse plus détaillée sur ce que toutes les lignes de code qui tombent dans ce moyen package-lock.json
peut ĂȘtre trouvĂ© dans le fichier package.json
dans le rĂ©fĂ©rentiel Gatsby.js . Il y a beaucoup de dĂ©pendances directes, Ă savoir, selon les calculs de npm , 132. Si chacune de ces dĂ©pendances a au moins une autre dĂ©pendance, alors le nombre total de dĂ©pendances du projet doublera - et il aura 264 dĂ©pendances. Bien sĂ»r, dans le monde rĂ©el, ce n'est pas le cas. Chaque dĂ©pendance de projet directe a plus d'une dĂ©pendance inhĂ©rente. Par consĂ©quent, la liste des dĂ©pendances du projet est trĂšs longue.Par exemple, nous allons nous intĂ©resser au nombre de fois oĂč la bibliothĂšque lodash est utilisĂ©e comme dĂ©pendance pour d'autres packages :$ npm ls lodash
example-js-package@1.0.0
ââ⏠gatsby@2.19.28
ââ⏠@babel/core@7.8.6
â ââ⏠@babel/generator@7.8.6
â â âââ lodash@4.17.15 deduped
â ââ⏠@babel/types@7.8.6
â â âââ lodash@4.17.15 deduped
â âââ lodash@4.17.15 deduped
ââ⏠@babel/traverse@7.8.6
â âââ lodash@4.17.15 deduped
ââ⏠@typescript-eslint/parser@2.22.0
â ââ⏠@typescript-eslint/typescript-estree@2.22.0
â âââ lodash@4.17.15 deduped
ââ⏠babel-preset-gatsby@0.2.29
â ââ⏠@babel/preset-env@7.8.6
â ââ⏠@babel/plugin-transform-block-scoping@7.8.3
â â âââ lodash@4.17.15 deduped
â ââ⏠@babel/plugin-transform-classes@7.8.6
â â ââ⏠@babel/helper-define-map@7.8.3
â â âââ lodash@4.17.15 deduped
â ââ⏠@babel/plugin-transform-modules-amd@7.8.3
â â ââ⏠@babel/helper-module-transforms@7.8.6
â â âââ lodash@4.17.15 deduped
â ââ⏠@babel/plugin-transform-sticky-regex@7.8.3
â ââ⏠@babel/helper-regex@7.8.3
â âââ lodash@4.17.15 deduped
...
Heureusement, la plupart de ces dĂ©pendances sont reprĂ©sentĂ©es par la mĂȘme version de lodash. Et avec cette approche, il n'y node_modules
aura qu'un seul dossier de bibliothĂšque lodash. Certes, ce n'est gĂ©nĂ©ralement pas tout Ă fait le cas. Parfois, diffĂ©rents packages nĂ©cessitent diffĂ©rentes versions du mĂȘme package. C'est pourquoi de nombreuses blagues sont apparues sur la taille Ă©norme du dossier node_modules
. Dans notre cas, cependant, tout n'est pas si mal:$ du -sh node_modules
200M node_modules
200 mégaoctets n'est pas si mal. J'ai vu comment la taille de ce dossier atteint facilement 700 Mo. Si vous souhaitez savoir quels modules occupent le plus d'espace, vous pouvez exécuter la commande suivante:$ du -sh ./node_modules/* | sort -nr | grep '\dM.*'
17M ./node_modules/rxjs
8.4M ./node_modules/@types
7.4M ./node_modules/core-js
6.8M ./node_modules/@babel
5.4M ./node_modules/gatsby
5.2M ./node_modules/eslint
4.8M ./node_modules/lodash
3.6M ./node_modules/graphql-compose
3.6M ./node_modules/@typescript-eslint
3.5M ./node_modules/webpack
3.4M ./node_modules/moment
3.3M ./node_modules/webpack-dev-server
3.2M ./node_modules/caniuse-lite
3.1M ./node_modules/graphql
...
Oui, rxjs est un paquet insidieux.Voici une commande simple qui permet de réduire la taille du dossier node_modules
et de simplifier sa structure:$ npm dedup
moved 1 package and audited 18701 packages in 4.622s
51 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Pendant la dĂ©duplication, npm essaie de simplifier la structure de l'arborescence de dĂ©pendances en recherchant les dĂ©pendances utilisĂ©es par d'autres dĂ©pendances et en les dĂ©plaçant afin qu'elles puissent ĂȘtre partagĂ©es. Cela s'applique Ă notre exemple lodash. De nombreux packages sont utilisĂ©s lodash @4.17.15
, par conséquent, pour garantir leur opérabilité, il suffit d'installer cette version de la bibliothÚque une seule fois. Bien sûr, c'est la situation dans laquelle nous nous trouvons depuis le tout début, uniquement en établissant des dépendances. Si dans le processus de travail sur un projet package.json
ajouter de nouvelles dépendances, il est parfois recommandé de se souvenir de l'équipe npm dedup
. Si vous utilisez le gestionnaire de paquets de fils, une commande similaire ressemble à la déduplication de fils. Mais, en fait, cela n'est pas nécessaire, car l'optimisation des dépendances est effectuée automatiquement lorsque la commande est exécutée yarn install
.Visualisation des dépendances
IntĂ©ressĂ© par une reprĂ©sentation graphique des dĂ©pendances de votre projet? Si c'est le cas, vous pouvez crĂ©er une telle prĂ©sentation Ă l'aide d'outils spĂ©ciaux. Examinons certains d'entre eux.Ce qui suit est un rĂ©sultat de visualisation de dĂ©pendance obtenu en utilisant npm.anvaka.com/ .Visualisation des dĂ©pendances Ă l'aide de npm.anvaka.comVous pouvez voir ici les dĂ©pendances des dĂ©pendances du package de projet Gatsby.js. Le rĂ©sultat est similaire Ă un Ă©norme site Web. Le projet Gatsby.js a tellement de dĂ©pendances que ce «web» a presque «bloqué» mon navigateur. Maintenant , si vous ĂȘtes intĂ©ressĂ©, un lien vers ce diagramme. Il peut ĂȘtre prĂ©sentĂ© sous forme 3D.Voici une visualisation rĂ©alisĂ©e Ă l'aide de npm.broofa.com .Un fragment d'une visualisation de dĂ©pendance faite en utilisant npm.broofa.comCeci est similaire Ă un organigramme. Elle, pour Gatsby.js, s'avĂšre trĂšs compliquĂ©e. Vous pouvez y jeter un Ćil ici . ĂlĂ©mentscircuit peuvent ĂȘtre colorĂ©s selon les estimations de npms.io . Vous pouvez tĂ©lĂ©charger votre propre fichier sur le sitepackage.json
.L'outil Package Phobia vous permet de déterminer l'espace dont il a besoin avant d'installer un package.Informations sur le package reçues à l'aide de Phobie du packageVous pouvez découvrir ici la taille du package publié et la quantité d'espace disque nécessaire aprÚs l'installation.Conclusion: une grande puissance s'accompagne d'une grande responsabilité
En fin de compte, je tiens à dire que JavaScript et NPM sont d'excellents outils. La bonne chose est que les développeurs modernes ont la possibilité d'utiliser un énorme ensemble de dépendances. L'exécution de la commande npm install
pour vous éviter d'écrire quelques lignes de code est si facile que nous oublions parfois les conséquences.Maintenant que vous avez lu jusqu'à présent, vous devriez avoir une compréhension plus complÚte des fonctionnalités de l'arborescence des dépendances de npm-project. Si vous ajoutez une bibliothÚque au projet qui est trÚs grande, ou si vous explorez simplement les dépendances de votre projet, vous pouvez toujours profiter de ce que nous avons discuté ici et analyser les dépendances.Chers lecteurs! Voulez-vous utiliser le moins de dépendances possible dans vos projets npm?