Редактори, командний рядок та інструментарій автоматизації
Головне: Редактори розвʼязують «добре бачити, правильно редагувати», а командний рядок — «пакетно, повторювано». На кожному боці є кілька інструментів, що лишаються корисними десятиліття.

Коротко: обирайте редактор за сценарієм — CodeMirror 6 для утилітарних сайтів і мобільних, Monaco лише коли потрібен повний досвід IDE; пакетну роботу доручайте jq плюс трьом перевіркам CI для синтаксису, структури й стилю, і завжди передавайте аргументи через jq --arg.
Епоха ручної перевірки JSON мала б закінчитися: усе, що машина може повторити, не залишайте людському оку.
1. Редактори в браузері
1.1 Мінімальна інтеграція 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 перед важкою роботою; не форматуйте на кожне натискання
scheduleParse(update.state.doc.toString());
}
}),
],
});
Чотири моменти:
json()дає підсвічування синтаксису й сполучення дужок — не пишіть своє;jsonParseLinter()створює маркери помилок на рівні рядка й стовпця; поєднайте зlintGutter(), щоб показувати іконки поруч із номерами рядків;updateListenerобов'язково треба debounce; викликJSON.parseна ста тисячах рядків при кожному натисканні помітно гальмуватиме;- Великі документи потребують оптимізацій поза
EditorView.lineWrapping, щоб не відображати все одразу (CodeMirror 6 за замовчуванням відображає за вікном перегляду, що є покращенням порівняно зі старими версіями).
1.2 Згортання й структура
CodeMirror 6 має вбудоване згортання; у сценаріях JSON ви зазвичай згортаєте за «об'єктом/масивом»:
import { foldGutter, foldKeymap } from '@codemirror/language';
import { keymap } from '@codemirror/view';
З foldGutter() і keymap.of(foldKeymap) користувачі можуть згортати довгі масиви комбінацією клавіш.
1.3 Вибір між CodeMirror і Monaco
| Вимір | CodeMirror 6 | Monaco |
|---|---|---|
| Розмір пакета | Малий, модульний | Великий (кілька мегабайт) |
| Мобільні | Добре підтримуються | Посередній досвід |
| Мовні сервіси | Треба будувати свої | Багаті, вбудовані |
| Ціна кастомізації | Низька | Середня |
Утилітарні сайти й мобільність на першому місці → CodeMirror; повний досвід IDE (кілька файлів, перехід до визначення, доповнення) → Monaco.
2. Командний рядок: шість частих рецептів jq
jq для JSON — те саме, що sed + awk для тексту; вивчення лише малої частини його синтаксису покриває вісімдесят відсотків повсякденних потреб.
# 1. Вибір полів (найпоширеніше)
jq '.data.items[].name' response.json
# 2. Фільтр + переформування
jq '.data.items[] | select(.price < 10) | {id, price}' response.json
# 3. Агрегати (довжина, сума, максимум)
jq '[.items[] | .price] | {count: length, total: add, max: max}' response.json
# 4. Групування й агрегація
jq '[.items[]] | group_by(.category) | map({category: .[0].category, count: length})' response.json
# 5. Об'єднати кілька файлів у масив
jq -s '.' part-*.json > merged.json
# 6. Обробка JSON Lines рядок за рядком
jq -c 'select(.level == "error")' app.jsonl
# Поширені перемикачі виводу
jq -r '.data.name' # Прибрати лапки, щоб чисто передати в оболонку
jq -c '.' # Компактний вивід, один рядок
jq --arg id "$ID" '.id == $id' # Передавати аргументи безпечно, уникаючи ін'єкції через склеювання
--arg вартий окремої згадки: склеювання змінної безпосередньо в вираз ламається, щойно значення містить лапки, тоді як --arg дозволяє jq самому обробити екранування.
2.1 Інші інструменти стисло
| Інструмент | Призначення | Одним реченням |
|---|---|---|
yq |
Конвертація YAML/JSON/XML | Синтаксис, схожий на jq, робоча конячка для конфігураційних файлів |
dasel |
Уніфіковані запити між форматами | Підтримує JSON/YAML/TOML/XML/CSV |
fx |
Інтерактивний перегляд JSON | Клікайте в терміналі, добре для дослідження |
jless |
Посторінковий перегляд у терміналі | Як less, із згортанням і пошуком |
gron |
Розгортання JSON у рядки, придатні для grep | Чудовий інструмент, щоб з'ясувати «на якому рівні це поле» |
ajv-cli |
Перевірка схем | Перевіряти файли JSON у CI |
Ідея gron особливо варта знання:
$ echo '{"a":{"b":[1,2]}}' | gron
json = {};
json.a = {};
json.a.b = [];
json.a.b[0] = 1;
json.a.b[1] = 2;
Після розгортання grep може знайти шлях, що набагато швидше за розгортання рівень за рівнем у редакторі.
3. Три шари перевірки в CI
| Шар | Інструмент | Що означає збій |
|---|---|---|
| Синтаксис | JSON.parse / jq empty |
Сам файл зламаний |
| Структура | ajv-cli + схема |
Відсутні поля, неправильні типи |
| Стиль | Prettier | Неузгоджене форматування, шумні diff |
# Синтаксис: пакетно перевірити кожен json-файл у репозиторії
find . -name '*.json' -not -path './node_modules/*' -print0 \
| xargs -0 -n1 jq empty
# Структура: перевірити за схемою
npx ajv-cli validate -s schemas/order.json -d 'fixtures/orders/*.json' --strict=false
# Стиль: лише перевірка, без змін
npx prettier --check "**/*.json"
Потрібні всі три шари, бо їхні повідомлення про помилки зовсім різні:
jq empty каже лише «який рядок зламаний», ajv каже «яке поле порушує яке ключове слово», а Prettier каже лише «форматування неузгоджене».
4. Хуки pre-commit
# Приклад .husky/pre-commit (фрагмент)
npx lint-staged
{
"lint-staged": {
"*.json": ["prettier --write", "jq empty"]
}
}
Будьте обережні з конфігураційними файлами інструментів, як-от package.json і tsconfig.json; не дозволяйте Prettier недбало змінювати їхні відступи —
деякі інструменти чутливі до форматування (валідний JSON не повинен бути, але на практиці це спричиняло проблеми). Можна виключити їх окремо.
5. Поради щодо налагодження
- Використовуйте
jq -eяк перевірку: код виходу дорівнює 1, коли результат виразу —falseабоnull, тож його можна одразу вставити в скрипти як перевірку; jq 'paths'перелічує всі шляхи, даючи швидкий огляд структури незнайомого документа;jq '.. | objects | keys'знаходить кожну назву ключа, що коли-небудь зустрічалася, що зручно для пошуку неузгодженого написання;- Форматуйте перед порівнянням у редакторі: неформатований diff — чистий шум; структурне порівняння, як-от
/diff, точніше.
6. Чек-лист
- [ ] Маркери помилок редактора точні до рядка й стовпця, а розбір проходить debounce;
- [ ] Скрипти команди передають аргументи через
jq --arg, а не склеюють рядки; - [ ] CI має всі три шари перевірки (синтаксис/структура/стиль);
- [ ] pre-commit обробляє лише додані файли, щоб повне сканування не сповільнювало коміти;
- [ ] Версії інструментів закріплені в
package.jsonабо.tool-versions.
Часті питання
Як обирати між CodeMirror 6 і Monaco?
Для утилітарних сайтів і мобільних надавайте перевагу CodeMirror 6: він малий, модульний, добре підтримується на мобільних, а підсвічування синтаксису, сполучення дужок і згортання можна компонувати за потреби. Звертайтеся до Monaco лише коли потрібен повний досвід IDE з кількома файлами, переходом до визначення й доповненням — ціною багатомегабайтного пакета й вищих зусиль на кастомізацію.
Чому CI потребує перевірки синтаксису, структури й стилю разом?
Три шари повідомляють зовсім різні помилки: jq empty каже, який рядок зламаний, ajv каже, яке поле порушує яке ключове слово, а Prettier каже лише, що форматування неузгоджене. Відкидання одного шару робить помилки інших легко неправильно прочитати, тож тримайте всі три й зупиняйтеся, щойно якийсь шар зазнає збою.
Чи покладатися на pre-commit замість перевірки в CI?
Ні. Хуки обробляють лише додані файли, що дає зворотний зв'язок за хвилину, але не може покрити весь репозиторій чи зміни, що обходять коміт. CI відповідає за повноту: тримайте pre-commit на доданих файлах, а повне сканування залишайте CI.