JSON Toolkit

JSON5 et JSONC : du JSON avec des commentaires

L’essentiel : Les deux dialectes existent parce qu'une configuration écrite par des humains a besoin de commentaires et de virgules finales, mais leur syntaxe et leur portée écosystémique diffèrent, et un mauvais choix bloque votre chaîne d'outils.

Débutant~10 min de lecturePublié le 2026-10-30Mis à jour le 2026-10-30
Illustration de l'article JSON5 et JSONC, du JSON avec des commentaires

L'essentiel : utilisez JSONC pour les commentaires dans la configuration VS Code et TypeScript, utilisez JSON5 lorsque vous avez besoin de la syntaxe de littéraux ES5.1 élargie comme les guillemets simples ou les clés non citées, et gardez les API publiques en JSON standard.

JSON standard n'autorise pas les commentaires, alors chaque équipe en écrit discrètement — jusqu'au jour où la compilation casse. Plutôt que de le faire en cachette, choisissez un dialecte approprié.

1. Deux dialectes aux motivations différentes

  • JSONC (JSON with Comments) : JSON standard plus commentaires et virgules finales, avec presque aucune autre modification de syntaxe. C'est le standard de fait de l'écosystème VS Code — settings.json, tsconfig.json et .eslintrc.json l'utilisent tous.
  • JSON5 : bien plus ambitieux, aligné directement sur le littéral d'objet ES5.1 — guillemets simples, clés non citées, hexadécimal, Infinity/NaN, continuation de ligne par antislash et signes + initiaux.

Une phrase pour les distinguer : JSONC rend seulement l'écriture confortable ; JSON5 permet d'écrire un fichier de configuration comme s'il s'agissait de JavaScript.

2. Tableau comparatif des syntaxes

Fonctionnalité JSON standard JSONC JSON5
Commentaires // /* */ ✗ ✓ ✓
Virgules finales ✗ ✓ ✓
Chaînes entre guillemets simples ✗ ✗ ✓
Clés non citées ✗ ✗ ✓
Nombres hexadécimaux ✗ ✗ ✓
Point décimal initial/final .5 5. ✗ ✗ ✓
Nombres commençant par + ✗ ✗ ✓
Infinity / NaN ✗ ✗ ✓
Continuation de fin de ligne \ ✗ ✗ ✓
Chaînes multilignes ✗ ✗ ✓ (réalisées par continuation)
Valeur racine quelconque ✓ ✓ ✓

La spécification complète de JSON5 dépasse à peine une page ; le paquet json5 est maintenu par la communauté depuis longtemps, et navigateurs comme Node se comportent à l'identique.

3. Analyse : deux API, deux types de capacité de positionnement

3.1 JSON5 : analyse simple du document entier

import JSON5 from 'json5';

const config = JSON5.parse(`
{
  // service port
  port: 8080,
  host: '0.0.0.0',
  features: ['json5', 'jsonc',],
  retries: 0x10,
}
`);

console.log(config.port, config.retries); // 8080 16

JSON5.parse renvoie un objet simple sans information de décalage — parce qu'il ne vise pas les scénarios d'édition, seulement la « lecture de configuration ».

3.2 JSONC : un arbre syntaxique avec décalages

La valeur de jsonc-parser ne réside pas dans l'analyse mais dans l'édition. Il offre trois couches d'API :

API Objectif Usage typique
parse Analyser en un arbre portant offset/length Coloration syntaxique, pliage, navigation
visit Parcours en profondeur ; le rappel reçoit le chemin du nœud Inspection à la manière de JSONPath
modify + applyEdits Produire une édition de texte minimale, puis l'appliquer au texte d'origine Modifier une valeur en conservant les commentaires
import { parseTree, findNodeAtLocation, modify, applyEdits } from 'jsonc-parser';

const text = `{
  // port configuration
  "server": {
    "port": 8080 // 80 in production
  }
}`;

const tree = parseTree(text);
const portNode = findNodeAtLocation(tree!, ['server', 'port']);
console.log(portNode?.offset, portNode?.length);

const edits = modify(text, ['server', 'port'], 3000, {
  formattingOptions: { insertSpaces: true, tabSize: 2 },
});
console.log(applyEdits(text, edits));

La sortie conserve les commentaires d'origine et ne remplace que les trois caractères de 8080 :

{
  // port configuration
  "server": {
    "port": 3000 // 80 in production
  }
}

C'est exactement ce que « modifier une configuration avec des expressions régulières » ne sait pas faire : une expression régulière ne sait pas quel 8080 modifier, ni que le 8080 à l'intérieur d'une chaîne doit rester intact.

3.3 Les messages d'erreur doivent porter des décalages

Les codes d'erreur de jsonc-parser sont des valeurs d'énumération ; les plus courants sont :

Code d'erreur Signification
InvalidSymbol Un caractère qui ne devrait pas être là est apparu
PropertyNameExpected Un nom de clé était attendu
ColonExpected Un deux-points était attendu
CommaExpected Une virgule était attendue
CloseBraceExpected L'objet n'a pas été fermé
UnexpectedEndOfComment Le commentaire n'a pas été fermé
InvalidEscapeCharacter Échappement invalide

Une fois offset converti en ligne et colonne, l'éditeur peut tracer le soulignement exactement sur la position fautive.

4. Quand utiliser lequel

Scénario Recommandation Raison
Corps de requêtes/réponses d'API publiques JSON standard Les dialectes ne sont pas pris en charge par les clients génériques
package.json, composer.json JSON standard Les gestionnaires de paquets ne comprennent que le JSON standard
tsconfig.json, .vscode/settings.json JSONC Valeur par défaut de l'écosystème, pris en charge nativement par la chaîne d'outils
Configuration d'application (nécessite des commentaires) JSONC ou YAML Les commentaires doivent survivre pendant que les outils peuvent encore lire et écrire
Besoin de Infinity, d'hexadécimal ou de littéraux complexes JSON5 La puissance d'expression la plus forte
Échange de données, journaux, caches Lignes délimitées ou JSON standard Le flux continu et l'universalité sont requis

Règle empirique : si le fichier doit être lu par un « outil non humain », privilégiez le JSON standard ; n'envisagez un dialecte que lorsque vous êtes certain qu'il est lu uniquement par votre propre code.

5. Trois sortes de risques introduits par les dialectes

5.1 Débordement du besoin

Quand un autre outil lit un fichier de configuration JSON5 et appelle JSON.parse, il plante purement et simplement. Le symptôme typique est « ça marche en local, ça échoue sur Docker » — parce que le conteneur suit un autre chemin de lecture.

Contre-mesure : ajoutez une vérification en CI dans le dépôt qui liste explicitement les fichiers autorisés à utiliser un dialecte ; tout le reste est validé comme du JSON standard.

5.2 Surprises autour de l'inférence de types

JSON5 autorise les clés non citées et les guillemets simples, mais ne permet pas d'introduire des constructions littérales comme des dates ou des expressions régulières — c'est toujours un format de données, pas une évaluation JavaScript. Certains ont cru que JSON5 pouvait exprimer new Date(), pour voir l'analyse échouer. JSON5 n'est pas eval.

5.3 Commentaires supprimés sans bruit

Ni JSON5.stringify ni JSON.stringify ne préservent les commentaires. Ainsi, « lire, ajuster une valeur, réécrire » perd tous les commentaires. Lorsque les commentaires doivent survivre, les seules options sont l'API d'édition de jsonc-parser, ou une bibliothèque YAML qui préserve les commentaires.

6. Recommandations pratiques

  • [ ] Tenez un tableau « type de fichier → format » dans la documentation d'équipe, pour que personne n'improvise ;
  • [ ] Enveloppez la lecture de configuration dans un unique loadConfig() qui décide en interne quel analyseur utiliser, afin que le code métier n'appelle jamais JSON.parse directement ;
  • [ ] Lors d'une modification programmatique d'une configuration commentée, utilisez modify + applyEdits ; ne réécrivez jamais tout le fichier ;
  • [ ] Validez aussi les fichiers dialectaux en CI (jsonc-parser pour JSONC, JSON5.parse pour JSON5), sinon les erreurs de syntaxe n'apparaissent qu'à l'exécution ;
  • [ ] Utilisez du JSON standard pour les interfaces publiques, les clés de cache et les charges utiles de files de messages.

FAQ

Comment choisir entre JSON5 et JSONC ?

Choisissez en fonction de l'exécution plutôt que du nombre de syntaxes : VS Code, TypeScript et ESLint lisent JSONC par défaut, si bien que JSONC offre la meilleure compatibilité ; ne recourez à JSON5 que si vous avez besoin de la syntaxe de littéraux ES5.1 élargie, comme les guillemets simples, les clés non citées ou Infinity. Aucun des deux dialectes ne convient aux réponses d'API publiques.

Pourquoi un analyseur JSON standard ne peut-il pas lire JSONC directement ?

JSONC autorise les commentaires et les virgules finales, alors que JSON.parse n'accepte que le JSON de la RFC 8259 et lève une erreur sur l'un comme sur l'autre. Lire du JSONC exige un analyseur tel que jsonc-parser, ou retirer les commentaires avant de confier le texte à un analyseur standard.

Les commentaires d'un fichier JSONC doivent-ils survivre aux modifications ?

Oui, mais uniquement via une API d'édition. modify et applyEdits de jsonc-parser modifient le nœud visé tout en préservant les autres commentaires ; analyser en objet puis sérialiser supprime tous les commentaires.