Aller au contenu principal
CuteJSON
↑↓ Naviguer Enter Selectionner Esc Fermer

Comment formater JSON sans perdre de précision

Publie 3 min de lecture Par Akash Kinkar Pandey

Formater JSON semble la chose la plus simple qu'un outil puisse faire : ajouter des espaces et des sauts de ligne pour qu'un humain puisse le lire. La plupart des formateurs font exactement cela en appelant JSON.parse puis JSON.stringify avec un argument d'indentation. Ce voyage aller-retour fonctionne pour le JSON que vous écrivez à la main et se rompt silencieusement pour le JSON que vous obtenez d'ailleurs.

Les deux bugs causés par le voyage aller-retour

JSON.parse transforme chaque nombre en un double JavaScript. Un double ne peut pas contenir chaque entier exactement après Number.MAX_SAFE_INTEGER, qui est 9007199254740991. Un ID snowflake, une clé primaire de base de données, ou un horodatage en nanosecondes peut facilement dépasser ce seuil, et une fois qu'il le fait, la re-sérialisation de la valeur analysée modifie les chiffres. 12345678901234567890 revient sous la forme 12345678901234567000. Personne ne le remarque tant que l'n'est pas erroné quelque part en aval.

Ce même voyage retour réordonne également les clés d'objet qui ressemblent à des nombres, car JSON.stringify parcourt les clés énumérables propres d'un objet JavaScript dans un ordre spécifique : les clés de type entier d'abord, en ordre ascendant, puis tout le reste en ordre d'insertion. Un document écrit comme {"2": "b", "1": "a"} revient sous la forme {"1": "a", "2": "b"}, ce qui est un document différent même si chaque valeur a survécu.

Ce que le formateur JSON fait à la place

Cet outil n'appelle jamais JSON.parse. Il tokenise votre document, valide le flux de tokens par rapport à RFC 8259, et réimprime à partir de ces tokens. Un nombre est copié comme les caractères exacts que vous avez écrits, pas re-encodé via un double. Une clé reste où vous l'avez placée. En collant

{"2":"second","1":"first","id":12345678901234567890,"note":"line1\nline2"}

et en appuyant Formater, on obtient :

{
  "2": "second",
  "1": "first",
  "id": 12345678901234567890,
  "note": "line1\nline2"
}

"2" reste avant "1", et le id à vingt chiffres revient exactement comme écrit. Seul l'espace a changé.

Lire une erreur

Si le document n'est pas du JSON valide, l'outil marque la ligne problématique dans la gouttière et nomme l'erreur réelle au lieu de citer le token sur lequel il s'est bloqué. Une virgule de fin avant une accolade fermante est signalée comme une virgule de fin, à la ligne où se trouve la virgule, pas à la fin du fichier où un analyseur simple abandonne.

Formater vs Minifier

Les deux boutons effectuent la même réimpression à partir des tokens ; seul l'espace diffère. Formater ajoute des sauts de ligne et la largeur d'indentation que vous avez choisie (2 espaces, 4 espaces, ou une tabulation). Minifier supprime chaque espace, tabulation et saut de ligne que JSON ne nécessite pas. Aucun ne modifie une valeur, il est donc sûr d'appuyer sur l'un ou l'autre autant de fois que vous le souhaitez, ou de basculer entre eux sans recoller.

Essayez-le sur un document avec un ID long ou un fichier de configuration avec des clés numériques, et comparez le résultat avec un formateur qui passe par JSON.parse. La différence apparaît immédiatement.

Retour aux articles