Back

Le Versionnage Sémantique expliqué

Le Versionnage Sémantique expliqué

Si vous avez déjà ouvert un fichier package.json et vous êtes demandé pourquoi une dépendance affiche ^1.4.2 tandis qu’une autre affiche ~2.0.1, vous êtes déjà confronté aux conséquences pratiques du Versionnage Sémantique. Comprendre le fonctionnement de SemVer vous aide à prendre de meilleures décisions concernant les mises à jour de dépendances, à éviter les builds cassés et à communiquer clairement les changements lorsque vous publiez vos propres packages.

Points clés à retenir

  • SemVer utilise un format MAJOR.MINOR.PATCH, où chaque segment signale un type de changement spécifique : rupture, ajout ou correction.
  • Les opérateurs de plage npm (^, ~ et versions exactes) contrôlent la manière dont les dépendances se mettent à jour, le caret étant l’opérateur par défaut et le plus permissif au sein d’une version majeure.
  • Les fichiers de verrouillage tels que package-lock.json garantissent des installations reproductibles entre les équipes et les environnements CI, indépendamment de la plage spécifiée.
  • Les versions inférieures à 1.0.0 sont considérées comme instables, et les balises de pré-version (par exemple, 1.0.0-beta.1) sont traitées comme des releases explicitement instables que npm n’installera pas via les plages normales sans demande explicite.
  • SemVer est un contrat social entre les mainteneurs et les consommateurs, et non un mécanisme de contrainte technique.

Qu’est-ce que le Versionnage Sémantique ?

Le Versionnage Sémantique (SemVer) est une spécification de versionnage qui attribue une signification aux numéros de version. Une version SemVer prend la forme MAJOR.MINOR.PATCH, où chaque numéro signale un type de changement spécifique :

  • MAJOR — un changement de rupture incompatible avec l’API publique précédente
  • MINOR — une nouvelle fonctionnalité ajoutée de manière rétrocompatible
  • PATCH — une correction de bug rétrocompatible

Lorsqu’un package passe de 2.6.9 à 3.0.0, quelque chose a rompu la rétrocompatibilité. Un passage de 2.6.9 à 2.7.0 ajoute des fonctionnalités sans rien casser. Un passage à 2.6.10 corrige un bug.

Une clarification importante : SemVer ne fonctionne de manière significative que lorsqu’un package dispose d’une API publique définie. Sans contrat clair entre le package et ses consommateurs, le numéro de version n’est qu’un simple numéro.

Comment npm utilise SemVer pour les plages de dépendances

Le versionnage npm s’appuie directement sur SemVer, mais la syntaxe des plages dans package.json est une couche supplémentaire — ce n’est pas SemVer en soi.

"dependencies": {
  "lodash": "^4.17.21",
  "axios": "~1.6.0",
  "react": "18.2.0"
}

Voici la signification de chaque opérateur de plage :

  • ^ (caret) — autorise les mises à jour MINOR et PATCH, mais pas MAJOR. ^4.17.21 accepte toutes les versions de 4.17.21 jusqu’à 5.0.0 exclu. Pour les releases 0.x, les plages avec caret sont plus restrictives : ^0.2.3 autorise les mises à jour inférieures à 0.3.0, et non toutes les versions 0.x.
  • ~ (tilde) — autorise les mises à jour PATCH lorsqu’une version mineure est spécifiée. ~1.6.0 accepte 1.6.x mais pas 1.7.0.
  • Version exacte18.2.0 installe uniquement cette version spécifique.

Le caret est l’opérateur par défaut de npm lorsque vous exécutez npm install. Il vous fournit automatiquement les corrections de bugs et les nouvelles fonctionnalités tout en vous protégeant des changements de rupture — à condition que l’auteur du package suive correctement SemVer. Cette hypothèse ne se vérifie pas toujours.

Pourquoi les fichiers de verrouillage sont importants

Votre package-lock.json enregistre la version exacte installée à un moment donné. Même si une plage telle que ^4.17.21 autorise des versions plus récentes, le fichier de verrouillage fige la version réellement utilisée au sein de votre équipe et de votre environnement CI. C’est pourquoi il est essentiel de versionner votre fichier de verrouillage pour des builds reproductibles.

Comprendre les releases 0.x et les versions pré-release

Deux aspects prennent souvent les développeurs au dépourvu :

Les releases 0.x sont instables par définition. Un package en 0.4.2 n’offre aucune garantie de compatibilité. Tout peut changer entre 0.4.2 et 0.5.0. Ne vous fiez pas aux règles de compatibilité de SemVer pour les packages n’ayant pas encore atteint 1.0.0.

Les versions pré-release telles que 1.0.0-beta.1 ont une priorité inférieure à celle de la release stable. npm n’installera pas une version pré-release sans demande explicite de votre part. Une plage classique comme ^1.0.0 ne se résoudra pas automatiquement vers 1.1.0-beta.1. Cela vous protège contre l’inclusion accidentelle de code instable.

Quand incrémenter quelle version

Si vous maintenez un package, utilisez ce guide :

Type de changementVersion à incrémenterExemple
Changement d’API avec ruptureMAJOR1.4.22.0.0
Nouvelle fonctionnalité, rétrocompatibleMINOR1.4.21.5.0
Correction de bug uniquementPATCH1.4.21.4.3
Dépréciation d’une fonctionnalité (sans suppression)MINOR1.4.21.5.0

Lorsque vous incrémentez MINOR, réinitialisez PATCH à zéro. Lorsque vous incrémentez MAJOR, réinitialisez à zéro à la fois MINOR et PATCH.

SemVer est un contrat, pas une garantie

SemVer offre un langage commun pour communiquer les changements. Mais techniquement, rien n’empêche un mainteneur de livrer un changement de rupture dans une release patch. Des outils tels que semantic-release peuvent automatiser le versionnage en se basant sur les messages de commit, réduisant ainsi les erreurs manuelles et aidant les équipes à respecter les conventions SemVer de manière plus cohérente.

Conclusion

Comprendre le versionnage npm et le versionnage des packages au prisme de SemVer fait de vous un consommateur plus confiant des packages open-source — et un éditeur plus responsable de vos propres packages. Le format est simple, mais ses implications sont profondes : chaque chiffre communique une intention, chaque opérateur de plage façonne le risque, et chaque fichier de verrouillage protège la reproductibilité. Considérez SemVer comme le vocabulaire commun qu’il a été conçu pour être, et votre gestion de dépendances deviendra sensiblement plus sereine.

FAQ

Vous pouvez recevoir des changements de rupture via ce qui devrait être une mise à jour sans risque, comme un patch ou un bump mineur. Pour vous protéger, versionnez votre package-lock.json, consultez les changelogs avant de mettre à jour, et envisagez des outils comme Renovate ou Dependabot qui affichent les notes de release en parallèle des incréments de version. Pour les dépendances critiques, figer des versions exactes constitue une mesure défensive raisonnable.

Le caret est l'opérateur par défaut de npm et fonctionne bien pour la plupart des applications, car il autorise les mises à jour mineures et patch au sein d'une version majeure. Le tilde est plus strict, n'acceptant que les mises à jour patch, ce qui convient aux projets privilégiant la stabilité par rapport aux nouvelles fonctionnalités. Pour les bibliothèques que vous publiez, privilégiez les plages avec caret afin que les consommateurs bénéficient automatiquement des améliorations rétrocompatibles.

La spécification SemVer indique explicitement que tout ce qui est inférieur à 1.0.0 est considéré comme étant en développement initial, où l'API publique ne doit pas être considérée comme stable. Les mainteneurs peuvent introduire des changements de rupture entre n'importe quelles releases 0.x sans incrémenter le numéro majeur. Une fois qu'un projet atteint 1.0.0, il s'engage à respecter pleinement les règles de compatibilité SemVer.

Vous devez la demander explicitement, soit en spécifiant la version exacte (npm install package@1.0.0-beta.1), soit en utilisant un tag (npm install package@next). Les plages standard telles que ^1.0.0 ignoreront entièrement les versions pré-release, ce qui empêche l'installation accidentelle de code instable dans les environnements de production.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay