JSON Toolkit

Editor, riga di comando e toolchain di automazione

In sintesi: Gli editor risolvono "vederlo chiaramente, modificarlo correttamente", mentre la riga di comando risolve "in batch, ripetibile". Su entrambi i fronti ci sono pochi strumenti che restano utili per un decennio.

Principiante~10 min di letturaPubblicato il 2026-10-30Aggiornato il 2026-10-30
Copertina di Editor, riga di comando e toolchain di automazione

In sintesi: scegli l'editor in base allo scenario — CodeMirror 6 per i siti di utilità e il mobile, Monaco solo quando ti serve l'esperienza completa di un IDE; lascia il lavoro in batch a jq più tre controlli in CI per sintassi, struttura e stile, e passa sempre gli argomenti con jq --arg.

L'epoca di controllare il JSON a mano dovrebbe essere finita: tutto ciò che una macchina può ripetere, non lasciarlo agli occhi umani.

1. Editor nel browser

1.1 Integrazione minima di 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) {
        // Debounce before doing heavy work; do not format on every keystroke
        scheduleParse(update.state.doc.toString());
      }
    }),
  ],
});

Quattro punti da notare:

  1. json() fornisce evidenziazione della sintassi e abbinamento delle parentesi — non scriverlo da te;
  2. jsonParseLinter() produce marker di errore a livello di riga e colonna; abbinalo a lintGutter() per mostrare le icone accanto ai numeri di riga;
  3. Il updateListener deve essere sottoposto a debounce; chiamare JSON.parse su centomila righe a ogni tasto premuto causerà un lag evidente;
  4. I documenti grandi richiedono ottimizzazioni oltre a EditorView.lineWrapping per evitare di renderizzare tutto in una volta (CodeMirror 6 renderizza per viewport per impostazione predefinita, un miglioramento rispetto alle versioni precedenti).

1.2 Folding e outline

CodeMirror 6 ha il folding integrato; negli scenari JSON di solito si piega per "oggetto/array":

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

Con foldGutter() e keymap.of(foldKeymap), gli utenti possono comprimere gli array lunghi con una scorciatoia da tastiera.

1.3 Scegliere tra CodeMirror e Monaco

Dimensione CodeMirror 6 Monaco
Dimensione del bundle Piccola, modulare Grande (diversi MB)
Mobile Ben supportato Esperienza mediocre
Servizi linguistici Bisogna costruirli Ricchi, integrati
Costo di personalizzazione Basso Medio

Siti di utilità e mobile-first → CodeMirror; esperienza completa di IDE (più file, go-to-definition, completamento) → Monaco.

2. Riga di comando: sei ricette jq ad alta frequenza

jq è per JSON ciò che sed + awk sono per il testo; imparare solo una piccola parte della sua sintassi copre l'ottanta per cento delle esigenze quotidiane.

# 1. Pick fields (the most common)
jq '.data.items[].name' response.json

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

# 3. Aggregates (length, sum, max)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json

# 4. Group and aggregate
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# 5. Merge multiple files into an array
jq -s '.' part-*.json > merged.json

# 6. Process JSON Lines line by line
jq -c 'select(.level == "error")' app.jsonl

# Common output switches
jq -r '.data.name'      # Strip the quotes so it pipes cleanly into the shell
jq -c '.'               # Compact output, one line
jq --arg id "$ID" '.id == $id'   # Pass arguments safely, avoiding injection through concatenation

--arg merita una menzione speciale: concatenare direttamente una variabile in un'espressione si rompe non appena il valore contiene virgolette, mentre con --arg è jq a gestire l'escape.

2.1 Altri strumenti in sintesi

Strumento Scopo In una frase
yq Conversione YAML/JSON/XML Sintassi simile a jq, il cavallo di battaglia dei file di configurazione
dasel Query unificata tra formati Supporta JSON/YAML/TOML/XML/CSV
fx Navigazione interattiva di JSON Clicca nel terminale, utile per esplorare
jless Navigazione paginata nel terminale Come less, con folding e ricerca
gron Appiattisce JSON in righe cercabili con grep Uno strumento fantastico per capire "a quale livello sta questo campo"
ajv-cli Validazione dello schema Valida i file JSON in CI

L'idea dietro gron vale la pena di essere conosciuta:

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

Una volta appiattito, grep può localizzare il percorso, molto più veloce che espandere livello per livello in un editor.

3. Tre livelli di validazione in CI

Livello Strumento Cosa significa un errore
Sintassi JSON.parse / jq empty Il file stesso è malformato
Struttura ajv-cli + schema Campi mancanti, tipi errati
Stile Prettier Formattazione incoerente, diff rumorosi
# Syntax: batch-validate every json file in the repository
find . -name '*.json' -not -path './node_modules/*' -print0 \
  | xargs -0 -n1 jq empty

# Structure: validate against a schema
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false

# Style: check only, do not modify
npx prettier --check "**/*.json"

Servono tutti e tre i livelli, perché i loro messaggi di errore sono completamente diversi: jq empty dice solo "quale riga è rotta", ajv dice "quale campo viola quale parola chiave", e Prettier dice solo "la formattazione è incoerente".

4. Hook pre-commit

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

Attenzione ai file di configurazione degli strumenti come package.json e tsconfig.json; non lasciare che Prettier li rientri casualmente — alcuni strumenti sono sensibili alla formattazione (il JSON valido non dovrebbe esserlo, ma in pratica ha causato problemi). Puoi escluderli singolarmente.

5. Suggerimenti di debug

  1. Usa jq -e come asserzione: il codice di uscita è 1 quando il risultato dell'espressione è false o null, quindi può entrare direttamente negli script come controllo;
  2. jq 'paths' elenca tutti i percorsi, dandoti una rapida panoramica della struttura di un documento che non conosci;
  3. jq '.. | objects | keys' trova ogni nome di chiave mai comparso, utile per scovare grafie incoerenti;
  4. Formatta prima di confrontare nell'editor: un diff non formattato è puro rumore; un confronto strutturale come /diff è più accurato.

6. Checklist

  • [ ] I marker di errore dell'editor sono precisi a riga e colonna, e il parsing è sottoposto a debounce;
  • [ ] Gli script del team passano gli argomenti con jq --arg invece di concatenare stringhe;
  • [ ] La CI ha tutti e tre i livelli di validazione (sintassi/struttura/stile);
  • [ ] Il pre-commit elabora solo i file in staging, così una scansione completa non rallenta i commit;
  • [ ] Le versioni degli strumenti sono fissate in package.json o .tool-versions.

FAQ

Come scelgo tra CodeMirror 6 e Monaco?

Per i siti di utilità e il mobile, preferisci CodeMirror 6: è piccolo, modulare e ben supportato sul mobile, e evidenziazione della sintassi, abbinamento delle parentesi e folding si possono comporre secondo necessità. Ricorri a Monaco solo quando ti serve l'esperienza completa di IDE con più file, go-to-definition e completamento — al costo di un bundle di diversi megabyte e di uno sforzo di personalizzazione maggiore.

Perché la CI ha bisogno insieme di controlli di sintassi, struttura e stile?

I tre livelli riportano errori completamente diversi: jq empty dice quale riga è rotta, ajv dice quale campo viola quale parola chiave, e Prettier dice solo che la formattazione è incoerente. Togliere un livello rende gli errori degli altri facili da fraintendere, quindi tieni tutti e tre e fermati non appena un livello fallisce.

Devo affidarmi al pre-commit invece di validare in CI?

No. Gli hook elaborano solo i file in staging, il che dà feedback entro un minuto ma non può coprire l'intero repository o le modifiche che aggirano il commit. La CI è responsabile della completezza: mantieni il pre-commit sui file in staging e lascia le scansioni complete alla CI.