JSON Toolkit

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ę.

Początkujący~10 min czytaniaOpublikowano 2026-10-30Zaktualizowano 2026-10-30
Okładka artykułu o edytorach, wierszu poleceń i łańcuchach automatyzacji

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:

  1. json() zapewnia podświetlanie składni i dopasowywanie nawiasów — nie pisz własnego;
  2. jsonParseLinter() produkuje znaczniki błędów na poziomie wiersza i kolumny; połącz go z lintGutter(), aby pokazać ikony obok numerów wierszy;
  3. updateListener musi być debounce'owany; wywoływanie JSON.parse na stu tysiącach wierszy przy każdym naciśnięciu klawisza będzie widocznie opóźniać;
  4. 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

  1. Używaj jq -e jako asercji: kod wyjścia wynosi 1, gdy wynik wyrażenia to false lub null, więc można go wstawić prosto do skryptów jako kontrolę;
  2. jq 'paths' wypisuje wszystkie ścieżki, dając szybki przegląd struktury nieznanego dokumentu;
  3. jq '.. | objects | keys' znajduje każdą nazwę klucza, która kiedykolwiek wystąpiła, co jest wygodne przy tropieniu niespójnej pisowni;
  4. 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.json lub .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.