JSON1

Sintaxe

JSON pode ter comentários?

Não. Não existe sintaxe de comentários em JSON e nunca existiu: o formato foi especificado como formato de intercâmbio de dados, e um comentário é uma nota entre pessoas, não dados. Essa resposta é curta, então o resto desta página trata do que fazer em vez disso, e de quais alternativas sobrevivem ao contato com um pipeline de build.

A resposta curta

Douglas Crockford, que especificou o JSON, removeu os comentários de propósito. A razão que ele declarou foi que as pessoas tinham começado a colocar diretivas de parsing neles, o que quebraria a interoperabilidade — a única propriedade pela qual o formato existe.

Então //, /* */ e # são todos erros de sintaxe, em qualquer parser conforme, em qualquer linguagem. Não há flag para ativá-los porque a gramática não tem produção nenhuma para eles.

O que acontece se você tentar

O erro quase nunca contém a palavra "comentário", e é por isso que isso confunde. O parser chega no / onde esperava uma vírgula ou uma chave de fechamento, e reporta isso.

As outras coisas que as pessoas presumem permitidas, e não são.
EscritoResultado
// nota ou # notaErro de sintaxe
/* nota */Erro de sintaxe
{"port": 8080,}Erro de sintaxe: vírgula final
{'port': 8080}Erro de sintaxe: aspas simples
{port: 8080}Erro de sintaxe: chave sem aspas

Entrada

{
  "port": 8080 // the port
}

Erro

Expected ',' or '}' after property value
in JSON at position 17 (line 2 column 16)
A posição 17 é a primeira /. Nada na mensagem menciona comentários, então a reação usual é ir procurar uma vírgula faltando.

JSON5 e JSONC

Existem dois superconjuntos, e a diferença importa na hora de escolher. Nenhum dos dois é JSON: um arquivo escrito em qualquer um deles será rejeitado pelo JSON.parse e por todo parser estrito.

  • JSONC é JSON mais comentários e vírgulas finais. Nada além disso. É o que o VS Code usa para o settings.json e o que o compilador do TypeScript aceita no tsconfig.json — e é por isso que ali os comentários funcionam e as pessoas concluem, com razão, que o JSON os permite.
  • JSON5 vai bem mais longe: chaves sem aspas, aspas simples, números hexadecimais, pontos decimais no início e no fim, Infinity e NaN, strings multilinha. Está mais perto de um literal de objeto JavaScript do que de JSON.
  • Nenhum tem tipo de mídia registrado. Não existe application/json5, então são formatos de arquivo para ferramentas que você controla, não formatos de transporte para uma API.
Onde é seguro usar cada um.
Arquivo de config próprioRequisição ou resposta de API
JSONSimSim
JSONCSe quem lê suportarNão
JSON5Se quem lê suportarNão

As quatro alternativas

Ordenadas por confiabilidade. As duas primeiras estão bem; a terceira tem um custo real; a quarta é uma armadilha.

  • 1. Use um formato que tenha comentários. Se o arquivo é configuração que uma pessoa mantém, YAML e TOML suportam comentários # como parte da gramática. Isso é a solução, não um contorno: um arquivo de configuração não tem motivo para ser JSON.
  • 2. Remova os comentários antes de parsear. É o padrão para config no estilo JSONC: uma passada de limpeza e depois JSON.parse. Use um parser JSONC de verdade e não uma expressão regular, porque uma regex vai destruir alegremente um // que apareça dentro de um valor de string, como uma URL.
  • 3. Uma chave acompanhante. JSON válido, e às vezes a única opção quando o arquivo precisa continuar estrito. O custo é que agora é dado: vai para os clientes, aparece nos diffs do objeto parseado, e qualquer schema com additionalProperties: false vai rejeitá-la.
  • 4. Não "comente" um bloco adicionando uma chave como `"_disabled"`. O bloco continua sendo parseado, continua ali, e a próxima pessoa não vai saber quais chaves aquele marcador cobria. Apague; o histórico está no controle de versão.

A abordagem da chave acompanhante

{
  "_comment": "port must match the load balancer",
  "port": 8080
}
JSON válido, e legível. Mas _comment agora é um campo dos seus dados, e um schema estrito vai rejeitá-lo.

Converter para YAML pelos comentários

Se o objetivo é um arquivo de configuração que uma pessoa possa anotar, converter o JSON para YAML uma vez e depois adicionar os comentários à mão é o caminho limpo. A direção contrária é onde se perde algo, e vale a pena ver exatamente como.

  • Comentários `#` de linha inteira são descartados. Comportamento correto: no JSON não há onde colocá-los.
  • Um `#` no fim de um escalar sem aspas passa a fazer parte do valor. O host voltou como "localhost # trailing comment". A própria especificação do YAML exige um espaço antes de um comentário em linha e o trata como comentário, então isso é uma limitação do conversor, não do YAML. Coloque o valor entre aspas ou o comentário em uma linha própria e o ciclo fica limpo.
  • Então trate a conversão como de mão única. Gere YAML a partir do JSON, anote o YAML e mantenha o YAML como fonte da verdade em vez de converter de ida e volta.

YAML com comentários

# the port the server binds to
port: 8080
host: localhost  # trailing comment
features:
  # experimental, off by default
  - search
  - export

Convertido para JSON

{
  "port": 8080,
  "host": "localhost  # trailing comment",
  "features": [
    "search",
    "export"
  ]
}
Os comentários de linha inteira sumiram, o que é esperado: o JSON não consegue guardá-los. Mas olhe o host.

O que fazer

A decisão depende, na verdade, do que o arquivo é. Dados que se movem entre máquinas não precisam de comentários. Um arquivo que uma pessoa edita precisa, e esse arquivo não deveria ter sido JSON.

  • Payloads de API: sem comentários, sem superconjuntos. Documente os campos em um schema ou na sua documentação de API, onde quem lê realmente vai olhar.
  • Uma config lida por uma única ferramenta que você controla: JSONC se a ferramenta suportar; se não, limpar e depois parsear.
  • Uma config que várias pessoas editam: mude para YAML ou TOML e pare de brigar com o formato.
  • Qualquer coisa que você precise explicar no lugar: se a explicação importa o bastante para ser escrita, importa o bastante para ir em um description do schema, que as ferramentas conseguem de fato mostrar a quem lê.
  • JSON para YAMLConverta uma vez e adicione os comentários que o YAML suporta nativamente.
  • JSON vs YAMLEm qual dos dois o arquivo deveria estar desde o começo.
  • Escape em JSONA outra regra que a especificação impõe e que surpreende as pessoas.
  • Guia completo de JSONA gramática completa, na ordem em que você precisa dela.