עורכים, שורת פקודה ושרשראות אוטומציה
שורה תחתונה: עורכים פותרים "לראות בבירור, לערוך נכון", בעוד שורת הפקודה פותרת "אצווה, ניתן לחזרה". לכל צד יש כמה כלים שנשארים שימושיים לעשור.

שורה תחתונה: בחרו את העורך לפי תרחיש — 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 before doing heavy work; do not format on every keystroke
scheduleParse(update.state.doc.toString());
}
}),
],
});
ארבע נקודות שכדאי לשים לב אליהן:
json()מספק הדגשת תחביר והתאמת סוגריים — אל תכתבו משלכם;jsonParseLinter()מייצר סמני שגיאה ברמת שורה/עמודה; שלבו אותו עםlintGutter()כדי להציג אייקונים לצד מספרי השורות;- ה-
updateListenerחייב להיות מעוכב (debounce); קריאה ל-JSON.parseעל מאה אלף שורות בכל הקשה תיצור השהיה מורגשת; - מסמכים גדולים דורשים אופטימיזציות מעבר ל-
EditorView.lineWrappingכדי להימנע מרינדור הכול בבת אחת (CodeMirror 6 מרנדר לפי viewport כברירת מחדל, וזה שיפור לעומת גרסאות ישנות יותר).
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 |
|---|---|---|
| גודל החבילה | קטן, מודולרי | גדול (כמה MB) |
| מובייל | נתמך היטב | חוויה בינונית |
| שירותי שפה | יש לבנות בעצמכם | עשירים, מובנים |
| עלות התאמה אישית | נמוכה | בינונית |
אתרי כלים ומובייל תחילה → CodeMirror; חוויית IDE מלאה (כמה קבצים, מעבר להגדרה, השלמה) → Monaco.
2. שורת פקודה: שישה מתכוני jq בתדירות גבוהה
jq הוא ל-JSON מה ש-sed + awk הם לטקסט; לימוד חלק קטן מהתחביר שלו מכסה שמונים אחוזים מהצרכים היומיומיים.
# 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 מגיע אזכור מיוחד: שרשור משתנה ישירות לתוך ביטוי נשבר ברגע שהערך מכיל מרכאות, בעוד ש---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-ים רועשים |
# 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"
צריך את כל שלוש השכבות, כי הודעות השגיאה שלהן שונות לחלוטין:
jq empty רק אומר "איזו שורה שבורה", ajv אומר "איזה שדה מפר איזה מילת מפתח", ו-Prettier רק אומר "הפורמט אינו עקבי".
4. ווי pre-commit
# .husky/pre-commit example (excerpt)
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. רשימת בדיקה
- [ ] סמני השגיאה בעורך מדויקים לשורה ולעמודה, והפרסור מעוכב;
- [ ] סקריפטים של הצוות מעבירים ארגומנטים עם
jq --argבמקום לשרשר מחרוזות; - [ ] ב-CI קיימות כל שלוש שכבות האימות (תחביר/מבנה/סגנון);
- [ ] pre-commit מעבד רק קבצים שנמצאים ב-staging, כך שסריקה מלאה לא מאטה את ה-commit;
- [ ] גרסאות הכלים מוצמדות ב-
package.jsonאו ב-.tool-versions.
FAQ
איך בוחרים בין CodeMirror 6 ל-Monaco?
לאתרי כלים ולמובייל, העדיפו CodeMirror 6: הוא קטן, מודולרי ונתמך היטב במובייל, ואפשר להרכיב הדגשת תחביר, התאמת סוגריים וקיפול לפי הצורך. פנו ל-Monaco רק כשצריך חוויית IDE מלאה עם כמה קבצים, מעבר להגדרה והשלמה — במחיר של חבילה בגודל כמה מגה-בייט ומאמץ התאמה גבוה יותר.
למה CI צריך בדיקות תחביר, מבנה וסגנון יחד?
שלוש השכבות מדווחות שגיאות שונות לחלוטין: jq empty אומר איזו שורה שבורה, ajv אומר איזה שדה מפר איזה מילת מפתח, ו-Prettier רק אומר שהפורמט אינו עקבי. השמטת שכבה אחת הופכת את השגיאות של האחרות לקשות לפירוש, ולכן שמרו על שלושתן ועצרו ברגע ששכבה נכשלת.
כדאי להסתמך על pre-commit במקום לאמת ב-CI?
לא. ווי מעבדים קבצים ב-staging בלבד, מה שנותן משוב בתוך דקה אבל לא מכסה את כל המאגר או שינויים שעוקפים את ה-commit. CI אחראי לשלמות: השאירו את pre-commit על קבצים ב-staging והשאירו סריקות מלאות ל-CI.