La respuesta corta
Douglas Crockford, que especificó JSON, quitó los comentarios deliberadamente. Su razón declarada fue que la gente había empezado a poner directivas de parseo en ellos, lo que habría roto la interoperabilidad, la única propiedad por la que el formato existe.
Así que //, /* */ y # son todos errores de sintaxis, en cualquier parser conforme, en cualquier lenguaje. No hay un flag para activarlos porque la gramática no tiene ninguna producción para ellos.
Qué pasa si lo intentas
El error casi nunca contiene la palabra "comentario", y por eso esto despista. El parser llega al / donde esperaba una coma o una llave de cierre, y reporta eso.
| Escrito | Resultado |
|---|---|
// nota o # nota | Error de sintaxis |
/* nota */ | Error de sintaxis |
{"port": 8080,} | Error de sintaxis: coma final |
{'port': 8080} | Error de sintaxis: comillas simples |
{port: 8080} | Error de sintaxis: clave sin comillas |
Entrada
{
"port": 8080 // the port
}Error
Expected ',' or '}' after property value in JSON at position 17 (line 2 column 16)
/. Nada en el mensaje menciona comentarios, así que la reacción habitual es buscar una coma que falta.JSON5 y JSONC
Existen dos superconjuntos, y la diferencia importa al elegir. Ninguno es JSON: un archivo escrito en cualquiera de los dos será rechazado por JSON.parse y por todo parser estricto.
- JSONC es JSON más comentarios y comas finales. Nada más. Es lo que usa VS Code para
settings.jsony lo que el compilador de TypeScript acepta entsconfig.json, y por eso ahí los comentarios funcionan y la gente concluye, razonablemente, que JSON los permite. - JSON5 va bastante más lejos: claves sin comillas, comillas simples, números hexadecimales, puntos decimales al principio y al final,
InfinityyNaN, cadenas multilínea. Está más cerca de un literal de objeto de JavaScript que de JSON. - Ninguno tiene un tipo de medio registrado. No existe
application/json5, así que son formatos de archivo para herramientas que controlas, no formatos de transporte para una API.
| Archivo de config propio | Petición o respuesta de API | |
|---|---|---|
| JSON | Sí | Sí |
| JSONC | Si el lector lo soporta | No |
| JSON5 | Si el lector lo soporta | No |
Las cuatro alternativas
Ordenadas por fiabilidad. Las dos primeras están bien; la tercera tiene un coste real; la cuarta es una trampa.
- 1. Usa un formato que tenga comentarios. Si el archivo es configuración que mantiene una persona, YAML y TOML soportan comentarios
#como parte de la gramática. Esto es la solución, no un parche: un archivo de configuración no tiene motivo para ser JSON. - 2. Quita los comentarios antes de parsear. Es lo estándar para config estilo JSONC: una pasada de limpieza y luego
JSON.parse. Usa un parser JSONC real y no una expresión regular, porque una regex destruirá alegremente un//que aparezca dentro de un valor de cadena, como una URL. - 3. Una clave acompañante. JSON válido, y a veces la única opción cuando el archivo debe seguir siendo estricto. El coste es que ahora es un dato: viaja a los clientes, aparece en los diffs del objeto parseado, y cualquier schema con
additionalProperties: falsela rechazará. - 4. No "comentes" un bloque añadiendo una clave como `"_disabled"`. El bloque se sigue parseando, sigue ahí, y la siguiente persona no sabrá qué claves cubría ese marcador. Bórralo; la historia está en el control de versiones.
El enfoque de la clave acompañante
{
"_comment": "port must match the load balancer",
"port": 8080
}_comment es ahora un campo de tus datos, y un schema estricto lo rechazará.Convertir a YAML por los comentarios
Si el objetivo es un archivo de configuración que una persona pueda anotar, convertir el JSON a YAML una vez y luego añadir los comentarios a mano es el camino limpio. La dirección contraria es donde se pierde algo, y vale la pena ver exactamente cómo.
- Los comentarios `#` de línea completa se descartan. Comportamiento correcto: en JSON no hay dónde ponerlos.
- Un `#` al final de un escalar sin comillas pasa a formar parte del valor.
hostvolvió como"localhost # trailing comment". La propia especificación de YAML exige un espacio antes de un comentario en línea y lo trata como comentario, así que es una limitación del convertidor, no de YAML. Pon el valor entre comillas o el comentario en su propia línea y el ciclo es limpio. - Así que trata la conversión como de una sola dirección. Genera YAML desde JSON, anota el YAML y mantén el YAML como fuente de verdad en lugar de convertir de ida y vuelta.
YAML con comentarios
# the port the server binds to port: 8080 host: localhost # trailing comment features: # experimental, off by default - search - export
Convertido a JSON
{
"port": 8080,
"host": "localhost # trailing comment",
"features": [
"search",
"export"
]
}host.Qué hacer
La decisión depende en realidad de para qué es el archivo. Los datos que se mueven entre máquinas no necesitan comentarios. Un archivo que edita una persona sí, y ese archivo no debería haber sido JSON.
- Payloads de API: sin comentarios, sin superconjuntos. Documenta los campos en un schema o en tu documentación de API, donde el lector va a mirar de verdad.
- Una config que lee una sola herramienta que controlas: JSONC si la herramienta lo soporta; si no, limpiar y luego parsear.
- Una config que editan varias personas: pásala a YAML o TOML y deja de pelear con el formato.
- Cualquier cosa que necesites explicar en el sitio: si la explicación importa lo bastante para escribirla, importa lo bastante para ir en un
descriptiondel schema, que las herramientas sí pueden mostrar al lector.
Pruébalo, o sigue leyendo
- JSON a YAMLConvierte una vez y añade los comentarios que YAML soporta de forma nativa.
- JSON vs YAMLEn cuál de los dos debería haber estado el archivo desde el principio.
- Escapado en JSONLa otra regla que impone la especificación y que sorprende a la gente.
- Guía completa de JSONLa gramática completa, en el orden en que la necesitas.