Je ne compte pas le nombre de fois où je me suis posé la question de ce que faisait les symboles devant les versions dans un package.json sans en être totalement sûrs. On va essayer d'y voir plus clair dans cet article.
Initialement, j'avais rédigé cet article en juillet 2021.
Il comportait une petite erreur sur l'utilisation du
caret. J'en ai donc profité pour le corriger et l'enrichir, et j'ai désormais un article dédié aupackage-lock.jsondans la même série.
Le SemVer, c’est quoi ?
Le SemVer (Semantic Versioning) est une convention de versionnement qui donne du sens aux numéros de version.
Si l'on s'appuie sur le site officiel, on retrouve la forme :
MAJEURE.MINEURE.CORRECTIF
Pour aller plus loin, n’hésitez pas à consulter semver.org et j'ai un article dédié sur le sujet : SemVer : les bases.
npm va venir enrichir ces notions avec des symboles. Ce sont des ranges (plage de versions en bon français). Elles indiquent ce que le projet accepte comme mises à jour, notamment lors des npm install.
Le symbole ^ : “jusqu’à la prochaine release majeure”
Le caret autorise les mises à jour tant que le premier chiffre non nul reste identique :
"react": "^1.2.3", // >=1.2.3 <2.0.0
"shiki": "^0.2.3", // >=0.2.3 <0.3.0
"tslib": "^0.0.3", // >=0.0.3 <0.0.4
Sur les versions
0.x, le caret est plus restrictif. Dans notre exemple,^0.2.3bloque le passage à tout ce qui est supérieur ou égal à0.3.0.
Le symbole ~ : “patchs uniquement”
Le tilde autorise des changements au niveau correctif, tant que la mineure ne bouge pas :
"shiki": "~1.2.3", // >=1.2.3 <1.3.0
"tslib": "~0.2.3", // >=0.2.3 <0.3.0
Les symboles >, >=, <, <=, = : comparateurs
Ces opérateurs fonctionnent comme des comparateurs classiques :
"react": ">1.2.3", // strictement supérieur
"shiki": ">=1.2.3", // supérieur ou égal
"tslib": "<2.0.0", // strictement inférieur
"axios": "<=2.0.0", // inférieur ou égal
"redux": "1.2.3", // (ou `=1.2.3`) version exacte
Le symbole - : inclusif
Un intervalle avec tiret est inclusif sur les bornes :
"tslib": "1.2.3 - 2.3.4", // >=1.2.3 <=2.3.4
"shiki": "0.2.0 - 0.4.2", // accepte 0.4.2 mais pas 0.4.3
Le symbole || : combiner des ensembles
Un intervalle avec le double pipe combine les deux ensembles :
"tslib": "^0.2.0 || >=0.5.0 <1.2.0" // Compatible avec l'ensemble ^0.2.0 ou >=0.5.0 <1.2.0
Le dist-tag : latest
Point important :
latestn’est pas une règle SemVer. C’est un dist-tag npm.
Exemple :
"shiki": "latest"
Par défaut, la commande npm install <pkg> installe la version pointée par le tag latest (si on ne met ni @<version> ni @<tag>). Un mainteneur peut alors faire pointer latest vers une version qui n’est pas forcément “la plus récente” au sens strict et utiliser d’autres tags (beta, next, etc.).
Bonus : x, * et les pré-releases -alpha, -beta
Exemples :
"tslib": "1.2.x", // >=1.2.0 <1.3.0
"shiki": "1.2.*", // >=1.2.0 <1.3.0
"redux": ">=1.2.3-0 <1.3.0" // inclut les pré-releases >=1.2.3-*
Les pré-releases (
-alpha,-beta) ont des règles spécifiques : par défaut, elles sont exclues des ranges. Pour les inclure, on peut utiliser une borne avec-0(ou une version pré-release) dans la range.
Conclusion
La première fois que j'ai rédigé cet article, j'avais essayé d'être le plus minimal possible. Je me suis rendu compte que c'était quand même plus sympa d'aller un peu plus loin, pour bien comprendre le fonctionnement du versionnement avec npm.
J'ai rédigé cet article pour m'en faire un mémo, l'avoir toujours sous la main et le mettre dans mes favoris. Vous pouvez en faire autant !
Sources
- Tableau officiel
npmsur le SemVer et les ranges : https://docs.npmjs.com/about-semantic-versioning - Calculateur de ranges
npm: https://semver.npmjs.com/
Top comments (0)