JSON Toolkit

JSON5 ו-JSONC: JSON עם הערות

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

מתחילכ-10 דקות קריאהפורסם 2026-10-30עודכן 2026-10-30
תמונת כריכה של JSON5 ו-JSONC, JSON עם הערות

שורה תחתונה: השתמשו ב-JSONC להערות בתוך הגדרות VS Code ו-TypeScript, השתמשו ב-JSON5 כשצריך את תחביר הליטרלים הרחב של ES5.1 כמו מרכאות בודדות או מפתחות בלי מרכאות, והשאירו APIs ציבוריים על JSON סטנדרטי.

JSON סטנדרטי אינו מתיר הערות, ולכן כל צוות כותב אותן בשקט בכל זאת — עד שיום אחד ה-build נשבר. במקום לעשות את זה בסתר, בחרו ניב ראוי.

1. לשני הניבים יש מניעים שונים

  • JSONC (JSON with Comments): JSON סטנדרטי בתוספת הערות ופסיקים בסוף, עם כמעט ללא שינויים תחביריים אחרים. זהו התקן בפועל של אקוסיסטם VS Code — settings.json, tsconfig.json ו-.eslintrc.json כולם משתמשים בו.
  • JSON5: שאפתני הרבה יותר, ומתיישר ישירות עם ליטרל האובייקט של ES5.1 — מרכאות בודדות, מפתחות בלי מרכאות, הקסדצימלי, Infinity/NaN, המשך שורה עם לוכסן אחורי וסימני + מובילים.

משפט אחד להבדיל ביניהם: JSONC רק הופך את הכתיבה לנוחה; JSON5 מאפשר לכתוב קובץ הגדרה כאילו היה JavaScript.

2. טבלת השוואת תחביר

תכונה JSON סטנדרטי JSONC JSON5
הערות // /* */ ✗ ✓ ✓
פסיקים בסוף ✗ ✓ ✓
מחרוזות במרכאות בודדות ✗ ✗ ✓
מפתחות בלי מרכאות ✗ ✗ ✓
מספרים הקסדצימליים ✗ ✗ ✓
נקודה עשרונית מובילה/נגררת .5 5. ✗ ✗ ✓
מספרים שמתחילים ב-+ ✗ ✗ ✓
Infinity / NaN ✗ ✗ ✓
המשך שורה עם \ בסוף שורה ✗ ✗ ✓
מחרוזות מרובות-שורות ✗ ✗ ✓ (מיושם דרך המשך שורה)
ערך כלשהו ברמה העליונה ✓ ✓ ✓

מפרט JSON5 המלא בקושי עולה על עמוד אחד; חבילת json5 מתוחזקת זה מכבר בידי הקהילה, והדפדפנים ו-Node מתנהגים באופן זהה.

3. פרסור: שני APIs, שני סוגי יכולת מיקום

3.1 JSON5: פרסור פשוט של המסמך כולו

import JSON5 from 'json5';

const config = JSON5.parse(`
{
  // service port
  port: 8080,
  host: '0.0.0.0',
  features: ['json5', 'jsonc',],
  retries: 0x10,
}
`);

console.log(config.port, config.retries); // 8080 16

JSON5.parse מחזיר אובייקט רגיל בלי מידע היסט — כי הוא לא מכוון לתרחישי עריכה, אלא רק ל"קריאת הגדרה".

3.2 JSONC: עץ תחביר עם היסטים

הערך של jsonc-parser אינו בפרסור אלא בעריכה. הוא מציע שלוש שכבות API:

API מטרה שימוש טיפוסי
parse פרסור לעץ שנושא offset/length הדגשת תחביר, קיפול, ניווט
visit מעבר עומק-תחילה; ה-callback מקבל את נתיב הצומת בדיקה בסגנון JSONPath
modify + applyEdits יצירת עריכת טקסט מינימלית, ואז יישומה על הטקסט המקורי שינוי ערך תוך שמירת הערות
import { parseTree, findNodeAtLocation, modify, applyEdits } from 'jsonc-parser';

const text = `{
  // port configuration
  "server": {
    "port": 8080 // 80 in production
  }
}`;

const tree = parseTree(text);
const portNode = findNodeAtLocation(tree!, ['server', 'port']);
console.log(portNode?.offset, portNode?.length);

const edits = modify(text, ['server', 'port'], 3000, {
  formattingOptions: { insertSpaces: true, tabSize: 2 },
});
console.log(applyEdits(text, edits));

הפלט שומר על ההערות המקוריות ומחליף רק את שלושת התווים של 8080:

{
  // port configuration
  "server": {
    "port": 3000 // 80 in production
  }
}

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

3.3 הודעות שגיאה חייבות לשאת היסטים

קודי השגיאה של jsonc-parser הם ערכי enum; הנפוצים הם:

קוד שגיאה משמעות
InvalidSymbol הופיע תו שלא אמור להיות שם
PropertyNameExpected צפוי שם מפתח
ColonExpected צפוי נקודתיים
CommaExpected צפוי פסיק
CloseBraceExpected האובייקט לא נסגר
UnexpectedEndOfComment ההערה לא נסגרה
InvalidEscapeCharacter הימלטות לא תקינה

ברגע ש-offset מומר לשורה ולעמודה, העורך יכול לצייר את הקו המסולסל בדיוק על המיקום הפוגע.

4. מתי להשתמש במה

תרחיש המלצה סיבה
גופי בקשה/תגובה של API ציבורי JSON סטנדרטי לקוחות כלליים אינם תומכים בניבים
package.json, composer.json JSON סטנדרטי מנהלי חבילות מבינים רק JSON סטנדרטי
tsconfig.json, .vscode/settings.json JSONC ברירת המחדל של האקוסיסטם, נתמך באופן מקורי בידי שרשרת הכלים
הגדרת יישום (צריכה הערות) JSONC או YAML ההערות חייבות להישמר בעוד כלים עדיין יכולים לקרוא ולכתוב אותו
צורך ב-Infinity, הקסדצימלי, ליטרלים מורכבים JSON5 כושר הביטוי החזק ביותר
החלפת נתונים, לוגים, מטמונים JSON מופרד שורות או סטנדרטי נדרשים זרימה ואוניברסליות

כלל אצבע: אם הקובץ ייקרא ב"כלי שאינו אנושי", העדיפו JSON סטנדרטי; שקלו ניב רק כשאתם בטוחים שהוא נקרא רק בידי הקוד שלכם.

5. שלושה סוגי סיכון שהניבים מכניסים

5.1 זליגה של הדרישה

כשכלי אחר קורא קובץ הגדרה ב-JSON5 וקורא ל-JSON.parse, הוא קורס מיד. הסימפטום הטיפוסי הוא "עובד מקומית, נכשל ב-Docker" — כי הקונטיינר מריץ נתיב קריאה אחר.

אמצעי נגד: הוסיפו בדיקת CI במאגר שמפרטת במפורש אילו קבצים מותרים להשתמש בניב; כל השאר מאומת כ-JSON סטנדרטי.

5.2 הפתעות סביב הסקת טיפוסים

JSON5 מתיר מפתחות בלי מרכאות ומרכאות בודדות, אבל הוא לא מאפשר להכניס קונסטרוקציות ליטרליות כמו תאריכים או ביטויים רגולריים — הוא עדיין פורמט נתונים, לא הערכת JavaScript. אנשים הניחו ש-JSON5 יכול לבטא new Date() וראו את הפרסור נכשל. JSON5 אינו eval.

5.3 הערות שנזרקות בשקט

גם JSON5.stringify וגם JSON.stringify אינם משמרים הערות. לכן "לקרוא פנימה, לשנות ערך, לכתוב חזרה" מאבד כל הערה. כשההערות חייבות לשרוד, האפשרויות היחידות הן API העריכה של jsonc-parser, או ספריית YAML שתומכת בשימור הערות.

6. המלצות מעשיות

  • [ ] שמרו טבלת "סוג קובץ → פורמט" בתיעוד הצוות כדי שאף אחד לא יאלתר;
  • [ ] עטפו את קריאת ההגדרה ב-loadConfig() יחיד שמחליט בפנים באיזה מפרסר להשתמש, כך שקוד עסקי לעולם לא קורא ל-JSON.parse ישירות;
  • [ ] בשינוי תוכנתי של הגדרה עם הערות, השתמשו ב-modify + applyEdits; לעולם אל תכתבו מחדש את כל הקובץ;
  • [ ] אמתו גם קובצי ניב ב-CI (jsonc-parser ל-JSONC, JSON5.parse ל-JSON5), אחרת שגיאות תחביר יצופו רק בזמן ריצה;
  • [ ] השתמשו ב-JSON סטנדרטי לממשקים ציבוריים, למפתחות מטמון ולמטענים של תורי הודעות.

FAQ

איך בוחרים בין JSON5 ל-JSONC?

בחרו לפי סביבת ההרצה ולא לפי מספר התכונות: VS Code, TypeScript ו-ESLint קוראים JSONC כברירת מחדל, ולכן JSONC נותן את התאימות הטובה ביותר; פנו ל-JSON5 רק כשצריך את תחביר הליטרלים הרחב של ES5.1, כמו מרכאות בודדות, מפתחות בלי מרכאות או Infinity. אף אחד מהניבים אינו מתאים לתגובות API ציבוריות.

למה מפרסר JSON סטנדרטי לא יכול לקרוא JSONC ישירות?

JSONC מתיר הערות ופסיקים בסוף, בעוד ש-JSON.parse מקבל רק JSON לפי RFC 8259 וזורק על שניהם. קריאת JSONC דורשת מפרסר כמו jsonc-parser, או הסרת הערות לפני העברת הטקסט למפרסר סטנדרטי.

האם הערות ב-JSONC צריכות לשרוד עריכות בקובץ?

כן, אבל רק דרך API עריכה. modify ו-applyEdits של jsonc-parser משנים את הצומת המבוקש תוך שמירת ההערות הנותרות; פרסור לאובייקט וסריאל שלו זורק כל הערה.