Créa-blog

#100JoursPourCoder
Projet Créa-code

Ressources pour développeur web

Théme de la semaine : Découvrir node.js

Node.js : le fichier package.json et package-lock.json

Temps de lecture estimé : 11 minutes
Accueil Javascript Node.js : le fichier package.json et package-lock.json

Lorsque vous commencez à explorer l’univers de Node.js, vous tombez très vite sur deux fichiers mystérieux : le package.json et le package-lock.json. Ils débarquent souvent sans prévenir, un peu comme un colissimo dont on ne se souvient pas avoir cliqué sur “commander”, mais ils finissent par devenir indispensables. Au début, ils paraissent techniques, voire intimidants, surtout quand on débute. Pourtant, comprendre leur rôle change radicalement votre manière de développer.

Ces fichiers ne sont pas simplement des feuilles de configuration inutiles. Ils servent de colonne vertébrale à un projet Node.js, un peu comme un carnet de bord détaillé qui permet de gérer, installer, partager et sécuriser toutes les dépendances de votre application. Une fois que vous maîtrisez leur fonctionnement, vous gagnez en autonomie, vous évitez les bugs difficiles à repérer, et vous travaillez de manière bien plus professionnelle.

  • Savoir distinguer clairement le rôle de chaque fichier pour mieux comprendre et stabiliser ses projets Node.js.
  • Apprendre à gérer ses dépendances avec confiance et éviter les erreurs fréquentes qui bloquent les débutants.
  • Gagner les bons réflexes pour maintenir un environnement de développement fiable, reproductible et facile à mettre à jour.

Dans ce chapitre, nous allons poser ensemble les bases, pas à pas. Vous verrez que tout est logique, et même parfois amusant quand on découvre comment Node.js réfléchit en coulisses.

Comprendre l’importance des dépendances dans un projet Node.js

Avant de rentrer dans le vif du sujet, il est essentiel de comprendre le contexte. Node.js est un environnement qui repose énormément sur les packages, c’est-à-dire des modules externes que l’on installe pour enrichir un projet. Cela peut être une librairie pour manipuler des dates, un outil pour compiler votre code, ou un framework complet comme Express.

Lorsque vous installez un package (par exemple en tapant npm install express), vous ne faites pas qu’ajouter un dossier dans votre projet. Ce geste anodin déclenche toute une mécanique interne : installation, versioning, compatibilité, historique, arborescence, dépendances des dépendances…

Sans outil de gestion, cela deviendrait vite ingérable. C’est exactement là que les fichiers package.json et package-lock.json entrent en scène. Ils apportent une méthode, une cohérence et un suivi automatique. Ce sont un peu les archivistes silencieux de votre projet.

Le package.json : la carte d’identité de votre projet

Le package.json est le premier fichier clé. Si vous deviez n’en retenir qu’un, ce serait celui-ci. Il se crée automatiquement lorsque vous exécutez la commande :

npm init

ou

npm init -y

On peut le considérer comme la fiche d’identité officielle de votre projet Node.js. À l’intérieur, vous retrouverez toutes les informations importantes : son nom, sa version, la liste des scripts, les dépendances, etc.

Voici un exemple minimaliste pour un projet fictif :

{
  "name": "mon-site-web",
  "version": "1.0.0",
  "description": "Un petit projet d'exemple",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.21.0"
  }
}

Chaque ligne a un sens précis, parfois discret, mais essentiel. Prenons le temps de décrire les principales parties.

Le nom et la version

Ces deux champs définissent l’identité du projet. Le nom doit être unique si vous publiez votre package sur npm, mais pour un projet local, il peut s’appeler comme vous le voulez.

La version suit généralement le format “semver”, c’est-à-dire une numérotation en trois parties, comme 1.0.0. Elle indique l’évolution du projet, ce qui est très utile lorsque vous travaillez en équipe ou lorsque vous déployez périodiquement des mises à jour.

La section scripts

C’est une zone particulièrement pratique. Elle permet de définir des commandes personnalisées. Par exemple :

"scripts": {
  "dev": "nodemon index.js",
  "test": "mocha"
}

Cela vous évite d’écrire des commandes longues et compliquées dans le terminal.
Au lieu de taper nodemon index.js, vous pouvez simplement exécuter npm run dev. C’est plus rapide, plus propre et bien plus efficace.

Les dépendances

Elles représentent l’ensemble des packages dont votre projet a besoin pour fonctionner. Si vous installez un module avec la commande :

npm install axios

Il apparaîtra automatiquement ici :

"dependencies": {
  "axios": "^1.6.0"
}

L’élément intéressant ici, c’est le symbole ^.

Il signifie : installer les mises à jour mineures et correctives, mais pas les mises à jour majeures susceptibles de casser le fonctionnement de votre projet. Node.js applique cela pour maintenir un équilibre entre modernité et stabilité.

Il m’est arrivé une fois de travailler sur un projet où la ligne d’axios avait été supprimée par erreur. Au prochain npm install, impossible de faire fonctionner l’application. Donc, gardez toujours un oeil attentif sur votre package.json.

Pourquoi le package.json est indispensable

Le package.json n’est pas seulement un fichier décoratif. Il permet :

  • de recréer un projet sur un autre ordinateur,
  • de maintenir un historique précis des dépendances,
  • de gérer les scripts du projet,
  • et de communiquer clairement la configuration du projet à tout développeur ou outil externe.

Si vous le supprimez, c’est un peu comme effacer la mémoire du projet. Vous pourrez certes récupérer les dossiers à la main, mais vous perdrez toute traçabilité. C’est pour cela que les projets professionnels le versionnent systématiquement dans Git.

Le package-lock.json : le gardien des versions exactes

Si le package.json est la carte d’identité, le package-lock.json est le carnet d’historique ultra précis. Un fichier souvent moins compris, mais absolument incontournable pour garantir la stabilité d’un projet.

Lorsqu’un package est installé, npm ne se contente pas d’écrire son nom et sa version approximative dans le package.json. Il génère aussi le package-lock.json, qui enregistre la version exacte installée, ainsi que celles de toutes ses dépendances.

Ce fichier assure qu’un projet fonctionne exactement de la même façon sur toutes les machines, quel que soit le poste où il est installé. Il évite les surprises du type : “Ça marche chez moi, mais pas chez toi”.

Voici un extrait simplifié :

"node_modules/express": {
  "version": "4.21.0",
  "resolved": "https://registry.npmjs.org/express/-/express-4.21.0.tgz",
  "integrity": "sha512-xxxxxx",
  "dependencies": {
    "body-parser": "1.20.3",
    "send": "0.18.0"
  }
}

Chaque détail est enregistré :

  • le numéro de version précis,
  • l’URL,
  • le hash d’intégrité,
  • et les dépendances secondaires.

Ce niveau de précision est justement ce qui protège les projets professionnels des bugs imprévisibles.

Les différences essentielles entre package.json et package-lock.json

Maintenant que vous connaissez la fonction principale de chacun de ces fichiers, il est temps de comprendre ce qui les distingue réellement. Beaucoup de débutants pensent qu’ils se ressemblent, parce qu’ils ont un nom similaire et contiennent tous les deux des informations sur les dépendances. Pourtant, leur rôle n’a rien à voir. En réalité, ils fonctionnent en duo, un peu comme deux collègues qui occupent des postes très différents, mais qui ne peuvent pas travailler l’un sans l’autre.

Le package.json sert à décrire votre projet et les dépendances que vous souhaitez utiliser. Il ne fixe pas de versions exactes, il indique plutôt des « plages » de versions compatibles. C’est un fichier que vous modifiez volontairement, par exemple en ajoutant un nouveau script ou en changeant la description du projet.

À l’inverse, le package-lock.json sert à verrouiller les versions réellement installées, ligne par ligne. Vous ne le modifiez pas vous-même, c’est npm qui s’en charge automatiquement. Il s’assure que tous les développeurs d’un même projet auront exactement les mêmes versions, sans aucune variation, peu importe le contexte.

Pour illustrer cela, prenons un exemple simple. Dans votre package.json, vous pourriez avoir :

"dependencies": {
  "axios": "^1.6.0"
}

Mais dans votre package-lock.json, vous trouverez quelque chose comme :

"axios": {
  "version": "1.6.3",
  "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.3.tgz",
...
}

La différence saute aux yeux :

  • Le package.json dit simplement : « installez-moi axios version 1.6.0 ou toute version compatible ».
  • Le package-lock.json dit : « j’ai installé exactement la version 1.6.3, et voici sa source exacte ».

Grâce à ce mécanisme, npm peut reconstruire votre arborescence de dépendances de manière identique d’une machine à l’autre. Cela vous évite les situations où « ça marchait hier mais plus aujourd’hui », un classique chez les développeurs débutants et expérimentés.

Comment npm utilise ces deux fichiers au moment d’installer un package

Lorsque vous exécutez la commande npm install, npm suit une procédure bien précise. Comprendre cette procédure vous aide à anticiper certains comportements qui peuvent sembler étranges au début.

D’abord, npm lit votre package.json. Il vérifie les dépendances déclarées, les scripts, et les paramètres du projet. Ensuite, il consulte votre package-lock.json pour savoir si une version exacte d’un package a déjà été installée par le passé.

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?
  • Si une version précise est enregistrée dans le package-lock.json, npm la réinstalle à l’identique, même si une version plus récente existe. C’est la garantie de stabilité de votre projet.
  • Si le package-lock.json n’existe pas encore, npm installe les dernières versions compatibles indiquées par le package.json, puis génère un package-lock.json flambant neuf.

C’est d’ailleurs pour cela que lorsque vous supprimez votre dossier node_modules et relancez un npm install, tout fonctionne toujours parfaitement. Vous repartez d’une base propre, mais npm reconstruit scrupuleusement chaque dépendance à partir des deux fichiers.

Pourquoi vous ne devez jamais supprimer votre package-lock.json

Beaucoup de débutants ont le réflexe de supprimer ce fichier parce qu’il leur semble inutile. Il est long, illisible, et généré automatiquement… alors pourquoi le garder ?
La réponse est simple : le package-lock.json garantit la cohérence et la sécurité de votre projet Node.js.

Si vous le supprimez, npm devra réinstaller des versions potentiellement différentes de vos dépendances. Même si la version majeure reste la même, une mise à jour mineure peut introduire un changement de comportement, une fonction déplacée, ou un bug inattendu.

Garder ce fichier, c’est assurer :

  • la stabilité du projet,
  • la reproductibilité du code,
  • et la cohérence entre tous les environnements de développement.

Pour un développeur professionnel, c’est une règle absolue. Pour un débutant, c’est un geste simple qui évite de nombreux problèmes.

Comment lire et comprendre les notations de version dans le package.json

Lorsque vous parcourez la section des dépendances dans le package.json, vous remarquez des symboles tels que ^~ ou parfois l’absence de symbole. Ces petits caractères ont un impact énorme sur les versions installées.

Ce point mérite qu’on le détaille, car il peut perturber les nouveaux utilisateurs de Node.js.

Le symbole ^ signifie que npm peut installer toutes les mises à jour mineures tant que la version majeure ne change pas. Par exemple, ^4.21.0 permet d’installer 4.21.1, mais jamais 5.0.0.

Le symbole ~ est plus strict. Il autorise uniquement les mises à jour de patch, donc les changements dans la dernière partie du numéro de version. Par exemple, ~4.21.0 permet d’installer 4.21.7, mais pas 4.22.0.

Enfin, lorsque vous mettez un numéro sans symbole, comme "express": "4.21.0", vous verrouillez la version. npm installera exactement celle-ci, même si une version plus récente existe.

En tant que débutant, vous n’avez pas besoin de mémoriser toutes les règles dès le premier jour. Toutefois, comprendre la logique vous permet de garder le contrôle sur les versions installées et d’éviter les incohérences.

Pourquoi Node.js met autant l’accent sur la gestion des dépendances

Node.js est un écosystème où l’on installe des dizaines, parfois des centaines de packages. C’est une force, car cela permet de construire rapidement des fonctionnalités avancées. Mais c’est aussi une faiblesse, car une mise à jour majeure sur un seul package peut tout casser.

Le fichier package.json et le package-lock.json sont donc là pour créer une forme de discipline. Ils renforcent la fiabilité d’un projet, structurent votre environnement, et assurent que votre application repose sur des fondations stables plutôt que sur des versions imprévisibles.

Un environnement de développement sans ces deux fichiers serait comme une bibliothèque sans catalogue. Vous pourriez avoir les livres, mais vous ne sauriez jamais exactement lesquels, ni dans quel état, ni dans quelle version. Grâce à ces fichiers, Node.js sait toujours ce qu’il installe et comment.

Mettre à jour ses dépendances sans casser son projet

Une fois que l’on comprend comment fonctionnent le fichier package.json et le package-lock.json, on se demande naturellement comment mettre à jour ses dépendances sans faire s’effondrer toute son application. Cela peut paraître anodin, mais c’est l’une des zones où les débutants cassent le plus souvent leurs projets par accident.

Mettre à jour un package, c’est accepter un risque : celui qu’une nouvelle version modifie un comportement sur lequel votre application comptait. Heureusement, npm vous donne les outils pour effectuer ces mises à jour de manière contrôlée.

La commande la plus simple est npm update. Elle met à jour les packages uniquement dans la limite des versions autorisées par votre package.json.
Par exemple, si vous utilisez "express": "^4.21.0", un npm update pourra installer la version 4.22.0, mais jamais la 5.0.0. Cela respecte le suivi semver et vous évite les surprises.

Pour aller plus loin, vous pouvez exécuter npm outdated. Cette commande liste les dépendances que vous utilisez, les versions installées, les versions souhaitées, et les versions les plus récentes disponibles. C’est un outil précieux pour garder un œil sur ce qui évolue dans l’écosystème de Node.js.

Si un jour vous décidez de mettre à jour une version majeure, par exemple en passant de Express 4 à Express 5, il est conseillé de lire la documentation officielle, d’étudier les modifications apportées et de tester votre projet sur une branche distincte. Les versions majeures ne garantissent pas la compatibilité avec les versions précédentes, et un changement non anticipé peut briser un comportement que vous utilisiez sans même y penser.

Pour un projet professionnel ou un projet public, il est courant de réaliser ces mises à jour de manière progressive, en testant chaque étape pour éviter les erreurs. Même si vous travaillez seul, adopter cette discipline vous aidera à garder un projet propre, sûr et durable.

Que faire lorsque le package-lock.json change après une installation ?

Lorsque vous installez un nouveau package ou mettez à jour une dépendance, vous remarquez parfois que le package-lock.json se modifie massivement. Au début, cela peut surprendre. On pourrait croire à un bug ou à une manipulation accidentelle. En réalité, c’est parfaitement normal.

Le package-lock.json est une photographie exacte de l’état de vos dépendances. À chaque installation, npm met à jour les versions internes, les résolutions, ou même l’ordre dans lequel les modules sont installés. Cela crée un fichier vivant, en constante évolution.

  • Vous ne devez jamais modifier ce fichier manuellement.
  • Vous ne devez pas non plus l’ignorer dans votre gestion de version.
  • Chaque changement reflète une modification réelle dans votre environnement.

C’est pourquoi, dans les projets collaboratifs, vous verrez toujours le package-lock.json versionné dans Git, au même titre que le package.json. Sans lui, impossible de garantir que l’équipe utilise les mêmes versions.

Si vous travaillez à plusieurs et constatez des conflits dans ce fichier, traitez-les comme n’importe quel conflit de fusion : comparez la version de chacun, choisissez la meilleure, puis laissez npm reconstruire le fichier proprement. C’est un réflexe qui demande un peu de pratique, mais que l’on acquiert vite.

Exemple concret : du premier install à la reconstruction complète

Pour bien comprendre l’intérêt et le travail conjoint des deux fichiers, imaginons un scénario complet. Vous commencez un projet simple, avec un seul fichier index.js, puis :

  1. Vous initialisez le projet avec npm init -y.
  2. Votre package.json se crée automatiquement.
  3. Vous installez Express avec npm install express.
  4. npm ajoute express dans la section dependencies du package.json.
  5. npm génère le package-lock.json avec la version exacte téléchargée.
  6. npm crée le dossier node_modules avec tout l’écosystème d’Express.

Vous travaillez sur votre application, tout fonctionne correctement. Un mois plus tard, vous envoyez votre code sur un second ordinateur. Vous supprimez volontairement le dossier node_modules pour repartir d’une installation propre. Vous exécutez npm install.

  • npm lit votre package.json.
  • npm lit votre package-lock.json.
  • npm installe chaque dépendance exactement dans les versions enregistrées.

Votre projet redémarre sans un seul message d’erreur. Si vous n’aviez pas eu le package-lock.json, npm aurait été libre d’installer les versions “compatibles les plus récentes”, ce qui aurait pu casser votre application sans prévenir.

Ce simple scénario montre pourquoi ces fichiers existent et pourquoi ils travaillent toujours ensemble.

Les erreurs les plus fréquentes des débutants

Pour prévenir les situations compliquées, il est utile de connaître les pièges que rencontrent le plus souvent les nouveaux utilisateurs de Node.js. Le premier, vous l’avez deviné, est la suppression du package-lock.json.

Le second est la modification manuelle d’une version dans le package.json, sans comprendre que cette modification influencera l’ensemble des dépendances.

Un autre piège courant est d’ajouter une dépendance dans son projet mais d’oublier de la déclarer dans le package.json. Cela peut arriver lorsqu’on copie un dossier node_modules d’un ordinateur à un autre, ce qui est fortement déconseillé. Le package.json doit toujours être la seule source de vérité, jamais le dossier node_modules.

Il arrive aussi que certains développeurs débutants installent des packages en mode global alors qu’ils pensaient les installer localement. Cela devient un problème lorsqu’une commande fonctionne sur un ordinateur mais pas sur un autre, car la dépendance globale n’existe pas ailleurs.

Chaque erreur repose sur la même idée : un manque de synchronisation entre l’état réel du projet et les fichiers qui servent à le décrire. Le package.json et le package-lock.json sont justement là pour éviter ça.


Lorsque vous prenez le temps de comprendre le rôle du fichier package.json et du package-lock.json, vous découvrez que ces fichiers ne sont pas de simples éléments techniques. Ils structurent votre manière de travailler, stabilisent vos projets, et vous guident dans un écosystème où tout évolue vite. Tanpis si, au début, ils paraissent denses ou mystérieux, chaque ligne qu’ils contiennent joue un rôle précis.

Travailler avec Node.js sans comprendre ces deux fichiers, c’est un peu comme conduire sans connaître vos voyants de tableau de bord. On avance, certes, mais on manque des informations essentielles pour faire les bons choix et éviter les problèmes. En maîtrisant ces fichiers, vous gagnez en sérénité et en professionnalisme.

Avec le temps, vous allez développer un instinct : savoir quand mettre à jour une dépendance, quand observer un changement dans le package-lock.json, et comment reconstruire votre projet proprement. Ces compétences peuvent sembler modestes, mais elles sont au cœur de tout projet JavaScript moderne. Si vous les intégrez dès aujourd’hui, vos futurs projets seront plus solides, plus fiables, et surtout plus agréables à développer.