JSON Toolkit

Editores, linha de comando e cadeias de automação

Resumo: Editores resolvem "ver com clareza, editar corretamente", enquanto a linha de comando resolve "em lote, repetível". Cada lado tem algumas ferramentas que continuam úteis por uma década.

Iniciante~10 min de leituraPublicado em 2026-10-30Atualizado em 2026-10-30
Capa de Editores, linha de comando e cadeias de automação

Resumo da ópera: escolha o editor por cenário — CodeMirror 6 para sites utilitários e mobile, Monaco só quando precisar da experiência completa de IDE; deixe o trabalho em lote para o jq mais três verificações no CI para sintaxe, estrutura e estilo, e sempre passe argumentos com jq --arg.

A era de verificar JSON à mão já deveria ter acabado: tudo o que uma máquina consegue repetir, não deixe para os olhos humanos.

1. Editores no navegador

1.1 Integração mínima do CodeMirror 6

import { EditorView, basicSetup } from 'codemirror';
import { json, jsonParseLinter } from '@codemirror/lang-json';
import { linter, lintGutter } from '@codemirror/lint';

const view = new EditorView({
  parent: document.getElementById('editor')!,
  doc: '{"hello": "json"}',
  extensions: [
    basicSetup,
    json(),
    linter(jsonParseLinter()),
    lintGutter(),
    EditorView.updateListener.of((update) => {
      if (update.docChanged) {
        // Aplique debounce antes de fazer trabalho pesado; não formate a cada tecla
        scheduleParse(update.state.doc.toString());
      }
    }),
  ],
});

Quatro pontos a observar:

  1. json() fornece realce de sintaxe e correspondência de colchetes — não escreva o seu próprio;
  2. jsonParseLinter() produz marcadores de erro em nível de linha/coluna; combine-o com lintGutter() para mostrar ícones ao lado dos números de linha;
  3. O updateListener precisa de debounce; chamar JSON.parse em cem mil linhas a cada tecla vai travar visivelmente;
  4. Documentos grandes precisam de otimizações além de EditorView.lineWrapping para evitar renderizar tudo de uma vez (o CodeMirror 6 renderiza por viewport por padrão, o que é uma melhoria em relação a versões antigas).

1.2 Dobramento e sumários

O CodeMirror 6 tem dobramento embutido; em cenários JSON você normalmente dobra por "objeto/array":

import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';

Com foldGutter() e keymap.of(foldKeymap), os usuários podem recolher arrays longos com um atalho de teclado.

1.3 Escolhendo entre CodeMirror e Monaco

Dimensão CodeMirror 6 Monaco
Tamanho do bundle Pequeno, modular Grande (vários MB)
Mobile Bem suportado Experiência medíocre
Serviços de linguagem Você precisa construir os seus Ricos, embutidos
Custo de personalização Baixo Médio

Sites utilitários e mobile-first → CodeMirror; experiência completa de IDE (vários arquivos, ir para definição, autocompletar) → Monaco.

2. Linha de comando: seis receitas de jq de alta frequência

jq é para JSON o que sed + awk são para texto; aprender só uma pequena parte da sua sintaxe cobre oitenta por cento das necessidades do dia a dia.

# 1. Selecionar campos (o mais comum)
jq '.data.items[].name' response.json

# 2. Filtrar + remodelar
jq '.data.items[] | select(.price < 10) | {id, price}' response.json

# 3. Agregações (comprimento, soma, máximo)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json

# 4. Agrupar e agregar
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# 5. Mesclar vários arquivos em um array
jq -s '.' part-*.json > merged.json

# 6. Processar JSON Lines linha a linha
jq -c 'select(.level == "error")' app.jsonl

# Chaves de saída comuns
jq -r '.data.name'      # Remove as aspas para o resultado entrar limpo no shell
jq -c '.'               # Saída compacta, uma linha
jq --arg id "$ID" '.id == $id'   # Passe argumentos com segurança, evitando injeção por concatenação

--arg merece menção especial: concatenar uma variável diretamente em uma expressão quebra assim que o valor contém aspas, enquanto --arg deixa o jq cuidar do escaping.

2.1 Outras ferramentas em resumo

Ferramenta Finalidade Em uma frase
yq Conversão YAML/JSON/XML Sintaxe parecida com jq, o cavalo de batalha para arquivos de configuração
dasel Consulta unificada entre formatos Suporta JSON/YAML/TOML/XML/CSV
fx Navegação interativa em JSON Clique pelo terminal, bom para explorar
jless Navegação paginada no terminal Como less, com dobramento e busca
gron Achatar JSON em linhas grepáveis Ótima ferramenta para descobrir "em que nível está este campo"
ajv-cli Validação de schema Validar arquivos JSON no CI

A ideia por trás do gron vale especialmente a pena conhecer:

$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;

Uma vez achatado, o grep consegue localizar o caminho, o que é bem mais rápido do que expandir nível por nível em um editor.

3. Três camadas de validação no CI

Camada Ferramenta O que uma falha significa
Sintaxe JSON.parse / jq empty O arquivo em si está malformado
Estrutura ajv-cli + schema Campos ausentes, tipos errados
Estilo Prettier Formatação inconsistente, diffs barulhentos
# Sintaxe: valide em lote todos os arquivos json do repositório
find . -name '*.json' -not -path './node_modules/*' -print0 \
  | xargs -0 -n1 jq empty

# Estrutura: valide contra um schema
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false

# Estilo: apenas verificar, sem modificar
npx prettier --check "**/*.json"

Você precisa das três camadas, porque as mensagens de erro são completamente diferentes: o jq empty só diz "qual linha está quebrada", o ajv diz "qual campo viola qual palavra-chave" e o Prettier só diz "a formatação está inconsistente".

4. Hooks de pre-commit

# Exemplo de .husky/pre-commit (trecho)
npx lint-staged
{
  "lint-staged": {
    "*.json": ["prettier --write", "jq empty"]
  }
}

Cuidado com arquivos de configuração de ferramentas como package.json e tsconfig.json; não deixe o Prettier reindentá-los de qualquer jeito — algumas ferramentas são sensíveis à formatação (JSON válido não deveria ser, mas na prática isso já causou problemas). Você pode excluí-los individualmente.

5. Dicas de depuração

  1. Use jq -e como asserção: o código de saída é 1 quando o resultado da expressão é false ou null, então ele pode entrar direto em scripts como verificação;
  2. jq 'paths' lista todos os caminhos, dando uma visão rápida da estrutura de um documento desconhecido;
  3. jq '.. | objects | keys' encontra todo nome de chave que já apareceu, o que é prático para caçar grafias inconsistentes;
  4. Formate antes de comparar no editor: um diff sem formatação é puro ruído; uma comparação estrutural como /diff é mais precisa.

6. Lista de verificação

  • [ ] Os marcadores de erro do editor são precisos em linha e coluna, e a análise tem debounce;
  • [ ] Os scripts da equipe passam argumentos com jq --arg em vez de concatenar strings;
  • [ ] O CI tem as três camadas de validação (sintaxe/estrutura/estilo);
  • [ ] O pre-commit processa apenas arquivos preparados, para que uma varredura completa não atrase os commits;
  • [ ] As versões das ferramentas estão fixadas em package.json ou .tool-versions.

Perguntas frequentes

Como escolho entre CodeMirror 6 e Monaco?

Para sites utilitários e mobile, prefira CodeMirror 6: é pequeno, modular e bem suportado em mobile, e realce de sintaxe, correspondência de colchetes e dobramento podem ser compostos conforme a necessidade. Recorra ao Monaco apenas quando precisar da experiência completa de IDE com vários arquivos, ir para definição e autocompletar — ao custo de um bundle de vários megabytes e maior esforço de personalização.

Por que o CI precisa de verificações de sintaxe, estrutura e estilo juntas?

As três camadas relatam erros completamente diferentes: o jq empty diz qual linha está quebrada, o ajv diz qual campo viola qual palavra-chave e o Prettier só diz que a formatação está inconsistente. Remover uma camada faz os erros das outras ficarem fáceis de mal interpretar, então mantenha as três e pare assim que uma camada falhar.

Devo confiar no pre-commit em vez de validar no CI?

Não. Os hooks processam apenas arquivos preparados, o que dá feedback em um minuto mas não cobre o repositório inteiro nem alterações que contornam o commit. O CI é responsável pela completude: mantenha o pre-commit nos arquivos preparados e deixe as varreduras completas para o CI.