Editoren, Kommandozeile und Automatisierungs-Toolchains
Fazit: Editoren lösen „klar sehen, richtig bearbeiten“, die Kommandozeile löst „stapelweise, wiederholbar“. Jede Seite hat ein paar Werkzeuge, die ein Jahrzehnt nützlich bleiben.

Kurz gesagt: Wählen Sie den Editor nach Szenario – CodeMirror 6 für Utility-Seiten und Mobile, Monaco nur, wenn Sie die volle IDE-Erfahrung brauchen; überlassen Sie Stapelarbeit jq plus drei CI-Prüfungen für Syntax, Struktur und Stil, und übergeben Sie Argumente immer mit jq --arg.
Die Ära, JSON von Hand zu prüfen, sollte vorbei sein: Alles, was eine Maschine wiederholen kann, überlässt man nicht menschlichen Augen.
1. Editoren im Browser
1.1 Minimale CodeMirror-6-Integration
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());
}
}),
],
});
Vier Punkte sind zu beachten:
json()liefert Syntaxhervorhebung und Klammerpaarung – schreiben Sie das nicht selbst;jsonParseLinter()erzeugt Fehlermarker auf Zeilen-/Spaltenebene; paaren Sie es mitlintGutter(), um Symbole neben den Zeilennummern zu zeigen;- Der
updateListenermuss entprellt werden;JSON.parsebei jedem Tastendruck auf hunderttausend Zeilen läuft sichtbar nach; - Große Dokumente brauchen Optimierungen jenseits von
EditorView.lineWrapping, um nicht alles auf einmal zu rendern (CodeMirror 6 rendert standardmäßig nach Viewport, eine Verbesserung gegenüber älteren Versionen).
1.2 Folding und Gliederung
CodeMirror 6 hat eingebautes Folding; in JSON-Szenarien klappt man üblicherweise nach „Objekt/Array“:
import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';
Mit foldGutter() und keymap.of(foldKeymap) können Nutzer lange Arrays per Tastenkürzel zuklappen.
1.3 CodeMirror oder Monaco
| Dimension | CodeMirror 6 | Monaco |
|---|---|---|
| Bundlegröße | Klein, modular | Groß (mehrere MB) |
| Mobile | Gut unterstützt | Mittelmäßige Erfahrung |
| Sprachdienste | Selbst bauen | Reich, eingebaut |
| Anpassungsaufwand | Niedrig | Mittel |
Utility-Seiten und Mobile-First → CodeMirror; volle IDE-Erfahrung (mehrere Dateien, Go-to-Definition, Vervollständigung) → Monaco.
2. Kommandozeile: sechs häufige jq-Rezepte
jq ist für JSON, was sed + awk für Text sind; nur einen kleinen Teil seiner Syntax zu lernen deckt achtzig Prozent des Alltags ab.
# 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 verdient eine besondere Erwähnung: Eine Variable direkt in einen Ausdruck zu verketten bricht, sobald der Wert Anführungszeichen enthält, während --arg jq das Escaping erledigen lässt.
2.1 Andere Werkzeuge auf einen Blick
| Werkzeug | Zweck | In einem Satz |
|---|---|---|
yq |
YAML/JSON/XML-Konvertierung | Syntax ähnlich jq, das Arbeitstier für Konfigurationsdateien |
dasel |
Einheitliche Abfrage über Formate | Unterstützt JSON/YAML/TOML/XML/CSV |
fx |
Interaktives JSON-Browsen | Im Terminal herumklicken, gut zum Erkunden |
jless |
Seitenweises Browsen im Terminal | Wie less, mit Folding und Suche |
gron |
JSON in greppbare Zeilen abflachen | Ein großartiges Werkzeug, um herauszufinden, „auf welcher Ebene dieses Feld liegt“ |
ajv-cli |
Schema-Validierung | JSON-Dateien in CI validieren |
Die Idee hinter gron ist besonders wissenswert:
$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;
Einmal abgeflacht, kann grep den Pfad lokalisieren, was weit schneller ist, als im Editor Ebene für Ebene aufzuklappen.
3. Drei Validierungsschichten in CI
| Schicht | Werkzeug | Was ein Fehlschlag bedeutet |
|---|---|---|
| Syntax | JSON.parse / jq empty |
Die Datei selbst ist fehlerhaft |
| Struktur | ajv-cli + Schema |
Fehlende Felder, falsche Typen |
| Stil | Prettier | Uneinheitliche Formatierung, rauschende Diffs |
# 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"
Sie brauchen alle drei Schichten, weil ihre Fehlermeldungen völlig verschieden sind:
jq empty sagt nur „welche Zeile kaputt ist“, ajv sagt „welches Feld gegen welches Schlüsselwort verstößt“, und Prettier sagt nur „die Formatierung ist uneinheitlich“.
4. pre-commit-Hooks
# .husky/pre-commit example (excerpt)
npx lint-staged
{
"lint-staged": {
"*.json": ["prettier --write", "jq empty"]
}
}
Seien Sie vorsichtig mit Werkzeugkonfigurationsdateien wie package.json und tsconfig.json; lassen Sie Prettier sie nicht beiläufig neu einrücken –
manche Werkzeuge sind formatierungsempfindlich (gültiges JSON sollte es nicht sein, in der Praxis hat es aber Probleme verursacht). Sie können sie einzeln ausschließen.
5. Debugging-Tipps
jq -eals Zusicherung verwenden: Der Exit-Code ist 1, wenn das Ausdrucksergebnisfalseodernullist, es kann also direkt als Prüfung in Skripte;jq 'paths'listet alle Pfade, was einen schnellen Überblick über die Struktur eines unbekannten Dokuments gibt;jq '.. | objects | keys'findet jeden Schlüsselnamen, der je vorkam, praktisch für die Jagd nach uneinheitlicher Schreibweise;- Vor dem Vergleich im Editor formatieren: Ein unformatierter Diff ist reines Rauschen; ein struktureller Vergleich wie
/diffist genauer.
6. Checkliste
- [ ] Editor-Fehlermarker sind zeilen- und spaltengenau, und Parsen ist entprellt;
- [ ] Teamskripte übergeben Argumente mit
jq --arg, statt Strings zu verketten; - [ ] CI hat alle drei Validierungsschichten (Syntax/Struktur/Stil);
- [ ] pre-commit verarbeitet nur gestagte Dateien, damit ein vollständiger Scan Commits nicht verlangsamt;
- [ ] Werkzeugversionen sind in
package.jsonoder.tool-versionsfestgelegt.
FAQ
Wie wähle ich zwischen CodeMirror 6 und Monaco?
Für Utility-Seiten und Mobile bevorzugen Sie CodeMirror 6: Es ist klein, modular und auf Mobile gut unterstützt, und Syntaxhervorhebung, Klammerpaarung und Folding lassen sich nach Bedarf zusammensetzen. Greifen Sie nur dann zu Monaco, wenn Sie die volle IDE-Erfahrung mit mehreren Dateien, Go-to-Definition und Vervollständigung brauchen – zum Preis eines Multi-Megabyte-Bundles und höheren Anpassungsaufwands.
Warum braucht CI Syntax-, Struktur- und Stilprüfungen gemeinsam?
Die drei Schichten melden völlig verschiedene Fehler: jq empty sagt, welche Zeile kaputt ist, ajv sagt, welches Feld gegen welches Schlüsselwort verstößt, und Prettier sagt nur, dass die Formatierung uneinheitlich ist. Eine Schicht wegzulassen macht die Fehler der anderen leicht falsch lesbar, behalten Sie also alle drei und stoppen Sie, sobald eine Schicht scheitert.
Sollte ich mich auf pre-commit statt auf Validierung in CI verlassen?
Nein. Hooks verarbeiten nur gestagte Dateien, was innerhalb einer Minute Feedback gibt, aber nicht das ganze Repository oder Änderungen abdeckt, die den Commit umgehen. CI ist für Vollständigkeit zuständig: Lassen Sie pre-commit auf gestagten Dateien und überlassen Sie vollständige Scans der CI.