Edytory, wiersz poleceń i łańcuchy automatyzacji
Podsumowanie: Edytory rozwiązują „zobacz wyraźnie, edytuj poprawnie”, a wiersz poleceń rozwiązuje „wsadowo, powtarzalnie”. Po każdej stronie jest kilka narzędzi, które pozostają użyteczne przez dekadę.

Najważniejsze: wybieraj edytor według scenariusza — CodeMirror 6 dla witryn użytkowych i urządzeń mobilnych, Monaco tylko gdy potrzebujesz pełnego doświadczenia IDE; pracę wsadową zostaw jq plus trzem kontrolom CI dla składni, struktury i stylu, a argumenty zawsze przekazuj przez jq --arg.
Era ręcznego sprawdzania JSON-a powinna się skończyć: cokolwiek maszyna potrafi powtórzyć, nie zostawiaj ludzkim oczom.
1. Edytory w przeglądarce
1.1 Minimalna integracja 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());
}
}),
],
});
Cztery punkty do zapamiętania:
json()zapewnia podświetlanie składni i dopasowywanie nawiasów — nie pisz własnego;jsonParseLinter()produkuje znaczniki błędów na poziomie wiersza i kolumny; połącz go zlintGutter(), aby pokazać ikony obok numerów wierszy;updateListenermusi być debounce'owany; wywoływanieJSON.parsena stu tysiącach wierszy przy każdym naciśnięciu klawisza będzie widocznie opóźniać;- Duże dokumenty wymagają optymalizacji wykraczających poza
EditorView.lineWrapping, aby uniknąć renderowania całości naraz (CodeMirror 6 domyślnie renderuje według widocznego obszaru, co jest poprawą względem starszych wersji).
1.2 Zwijanie i konspekty
CodeMirror 6 ma wbudowane zwijanie; w scenariuszach JSON zwykle zwijasz według „obiekt/tablica”:
import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';
Dzięki foldGutter() i keymap.of(foldKeymap) użytkownicy mogą zwijać długie tablice skrótem klawiszowym.
1.3 Wybór między CodeMirror i Monaco
| Wymiar | CodeMirror 6 | Monaco |
|---|---|---|
| Rozmiar paczki | Mały, modułowy | Duży (kilka MB) |
| Urządzenia mobilne | Dobrze wspierane | Przeciętne doświadczenie |
| Usługi językowe | Trzeba zbudować samemu | Bogate, wbudowane |
| Koszt dostosowania | Niski | Średni |
Witryny użytkowe i podejście mobile-first → CodeMirror; pełne doświadczenie IDE (wiele plików, przejście do definicji, uzupełnianie) → Monaco.
2. Wiersz poleceń: sześć najczęstszych przepisów jq
jq jest dla JSON-a tym, czym sed + awk dla tekstu; nauczenie się tylko małej części jego składni pokrywa osiemdziesiąt procent codziennych potrzeb.
# 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 zasługuje na szczególne wyróżnienie: bezpośrednie wklejenie zmiennej do wyrażenia psuje się, gdy tylko wartość zawiera cudzysłowy, natomiast --arg pozwala jq zająć się ucieczką.
2.1 Inne narzędzia w skrócie
| Narzędzie | Cel | W jednym zdaniu |
|---|---|---|
yq |
Konwersja YAML/JSON/XML | Składnia podobna do jq, koń roboczy plików konfiguracyjnych |
dasel |
Ujednolicone odpytywanie między formatami | Obsługuje JSON/YAML/TOML/XML/CSV |
fx |
Interaktywne przeglądanie JSON | Klikasz w terminalu, dobre do eksploracji |
jless |
Stronicowane przeglądanie w terminalu | Jak less, ze zwijaniem i wyszukiwaniem |
gron |
Spłaszczanie JSON do linii przeszukiwalnych grepem | Świetne narzędzie do ustalenia „na którym poziomie jest to pole” |
ajv-cli |
Walidacja schematem | Waliduje pliki JSON w CI |
Idea stojąca za gron jest szczególnie warta poznania:
$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;
Po spłaszczeniu grep potrafi zlokalizować ścieżkę, co jest znacznie szybsze niż rozwijanie poziom po poziomie w edytorze.
3. Trzy warstwy walidacji w CI
| Warstwa | Narzędzie | Co oznacza porażka |
|---|---|---|
| Składnia | JSON.parse / jq empty |
Sam plik jest zniekształcony |
| Struktura | ajv-cli + schemat |
Brakujące pola, złe typy |
| Styl | Prettier | Niespójne formatowanie, hałaśliwe diffy |
# 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"
Potrzebujesz wszystkich trzech warstw, ponieważ ich komunikaty błędów są zupełnie różne:
jq empty mówi tylko „który wiersz jest zepsuty”, ajv mówi „które pole narusza które słowo kluczowe”, a Prettier mówi tylko „formatowanie jest niespójne”.
4. Haki pre-commit
# .husky/pre-commit example (excerpt)
npx lint-staged
{
"lint-staged": {
"*.json": ["prettier --write", "jq empty"]
}
}
Uważaj na pliki konfiguracyjne narzędzi, takie jak package.json i tsconfig.json; nie pozwól, by Prettier beztrosko zmieniał im wcięcia —
niektóre narzędzia są wrażliwe na formatowanie (poprawny JSON nie powinien być, ale w praktyce powodowało to problemy). Możesz je wykluczyć osobno.
5. Wskazówki dotyczące debugowania
- Używaj
jq -ejako asercji: kod wyjścia wynosi 1, gdy wynik wyrażenia tofalselubnull, więc można go wstawić prosto do skryptów jako kontrolę; jq 'paths'wypisuje wszystkie ścieżki, dając szybki przegląd struktury nieznanego dokumentu;jq '.. | objects | keys'znajduje każdą nazwę klucza, która kiedykolwiek wystąpiła, co jest wygodne przy tropieniu niespójnej pisowni;- Formatuj przed porównaniem w edytorze: niesformatowany diff to czysty szum; porównanie strukturalne, takie jak
/diff, jest dokładniejsze.
6. Lista kontrolna
- [ ] Znaczniki błędów edytora są precyzyjne do wiersza i kolumny, a parsowanie jest debounce'owane;
- [ ] Skrypty zespołu przekazują argumenty przez
jq --arg, zamiast sklejać łańcuchy; - [ ] CI ma wszystkie trzy warstwy walidacji (składnia/struktura/styl);
- [ ] pre-commit przetwarza tylko pliki w poczekalni, więc pełne skanowanie nie spowalnia commitów;
- [ ] Wersje narzędzi są przypięte w
package.jsonlub.tool-versions.
FAQ
Jak wybrać między CodeMirror 6 a Monaco?
Dla witryn użytkowych i urządzeń mobilnych preferuj CodeMirror 6: jest mały, modułowy i dobrze wspierany na urządzeniach mobilnych, a podświetlanie składni, dopasowywanie nawiasów i zwijanie można komponować według potrzeb. Po Monaco sięgaj tylko wtedy, gdy potrzebujesz pełnego doświadczenia IDE z wieloma plikami, przejściem do definicji i uzupełnianiem — kosztem paczki wielkości kilku megabajtów i wyższego nakładu dostosowania.
Dlaczego CI potrzebuje jednocześnie kontroli składni, struktury i stylu?
Trzy warstwy zgłaszają zupełnie różne błędy: jq empty mówi, który wiersz jest zepsuty, ajv mówi, które pole narusza które słowo kluczowe, a Prettier mówi tylko, że formatowanie jest niespójne. Pominięcie jednej warstwy sprawia, że błędy pozostałych łatwo źle odczytać, więc zachowaj wszystkie trzy i zatrzymuj się, gdy dowolna warstwa zawiedzie.
Czy polegać na pre-commit zamiast walidacji w CI?
Nie. Haki przetwarzają tylko pliki w poczekalni, co daje informację zwrotną w ciągu minuty, ale nie potrafi pokryć całego repozytorium ani zmian omijających commit. CI odpowiada za kompletność: zostaw pre-commit na plikach w poczekalni, a pełne skany zostaw CI.