JSON-diff

Порівняйте два JSON-документи й побачте, які саме поля додано, видалено чи змінено

JSON A (зліва / до)

JSON B (справа / після)

JSON-diff

Порівняйте два JSON-документи й побачте, які саме поля додано, видалено чи змінено

Можливості

  • Структурний diff між двома JSON-значеннями — обʼєкти, масиви та примітиви правильно обходяться (null трактується як скаляр, а не обʼєкт; баг typeof null виправлено)
  • Кожна різниця звітується як шлях RFC 6901 JSON Pointer (напр. `/users/0/email`), щоб одразу перейти до точного вузла у вкладених даних
  • Змінені записи показують значення «до» І «після» поруч, тож відразу зрозуміло, чи 'active' перейшов із true→false, чи змінилося число
  • Зведення: додано, видалено, змінено та незмінні листки — масштаб diff одним поглядом перед читанням деталей за шляхами
  • Окремий звіт про помилку розбору з кожного боку називає, який ввід не розібрався, і містить повідомлення JavaScript-движка — не доводиться вгадувати, A чи B пошкоджений
  • Кнопка «Копіювати звіт» видає весь diff (секції «Додано» / «Видалено» / «Змінено» плюс лічильник незмінних) як простий текст — вставляйте в код-рев'ю або повідомлення коміту
  • «Завантажити приклад» заповнює обидві панелі маленьким реалістичним прикладом (запис користувача зі змінами ролі + адреси), нові користувачі бачать diff без набирання тексту
  • Повністю на стороні клієнта: JSON A і JSON B розбираються та порівнюються у вашому браузері; нічого не завантажується, інструмент працює офлайн після завантаження сторінки

Як використовувати

  1. Вставте JSON «до» в ліве текстове поле (JSON A), JSON «після» — в праве (JSON B).
  2. Клацніть «Порівняти». Diff обчислюється рекурсивно: обʼєкти — за ключем, масиви — за індексом.
  3. Прочитайте зведення: скільки ключів додано, видалено, змінено та скільки листків збіглося.
  4. Прокрутіть списки шляхів, щоб побачити, які шляхи JSON Pointer змінилися; змінені рядки показують «до» → «після».
  5. Натисніть «Копіювати звіт», щоб отримати весь diff простим текстом — корисно для нотаток рев'ю, баг-репортів і повідомлень комітів.
  6. Використайте «Завантажити приклад», щоб побачити робочий приклад перед вставленням своїх даних.

Поради та найкращі практики

  • Спершу проженіть обидві сторони через JSON Formatter, якщо хочете, щоб текстовий diff також вважав структурно рівні документи без змін.
  • Для великих масивів, де важливий порядок, цей інструмент підходить ідеально; для множин — попередньо сортуйте за стабільним ключем.
  • Вивід шляху — RFC 6901, його можна передати безпосередньо в бібліотеки на кшталт fast-json-patch для програмного застосування змін.
  • Вставляйте звіт у описи PR, щоб показати рев'юерам, що саме змінилося у JSON конфігу чи фікстури.
  • Якщо помилки розбору вказують на конкретну колонку, повідомлення движка часто містить рядок/колонку у парсерів типу json5 — тут же використовується суворий JSON.parse, тож рядок/колонка — від хоста.

Запитання та відповіді

Як порівнюються масиви — за індексом чи за значенням?

За індексом. Елемент 0 A порівнюється з елементом 0 B, 1 з 1 і т. д. Якщо A довший, зайві хвостові індекси звітуються як «Видалено»; якщо B довший — як «Додано». Швидко й передбачувано, але одиничне вставлення на початку великого масиву каскадує у багато «змінено». Для нечутливих до порядку порівнянь (множини унікальних ID) спершу відсортуйте обидва масиви або перетворіть на обʼєкти з ключем-ідентифікатором.

Яка нотація шляхів у результаті?

RFC 6901 JSON Pointer: шляхи — це токени, розділені слешами, що спускаються деревом JSON. `/users/0/email` означає «властивість email елемента 0 у users». Ключі з `~` екрануються як `~0`, слеші — `~1`. Сам корінь — `/`. Та сама нотація використовується в патч-інструментах, JSON Schema instancePath і підказці вказівника json-formatter.

Як обробляється null?

null трактується як листове значення, не обʼєкт — хоча у JavaScript typeof null === 'object'. Тож {a: null} vs {a: {}} показується як змінене, а не рекурсує в порожній обʼєкт. {a: null} vs {a: null} — один незмінний листок, а {a: null} vs {a: 0} — змінене з «до=null після=0».

Чи diff працює з ключами зі спеціальними символами?

Так. Ключі з крапками, слешами, дужками чи тільдами екрануються за JSON Pointer у виводі шляху — `~` стає `~0`, `/` — `~1`. Тож ключ із буквальною назвою `a/b` показується як `/a~1b` — однозначно зворотно.

Чому лічильник незмінних не відповідає моїм очікуванням?

Незмінні рахуються на рівні ЛИСТКІВ — примітиви, рівні між A і B. Глибоко вкладений обʼєкт, чиє піддерево повністю ідентичне, дає по одній незмінній записі на листок, а не одну на все піддерево. Це робить лічильник справжньою перевіркою: «скільки примітивних значень залишилось».

Що якщо одна сторона null або порожня?

Порожній ввід парситься як null (тож `{a:1}` vs порожньо порівнюється з null і весь обʼєкт позначається як доданий). Літеральний `null` — валідний JSON-документ; порівняння двох null дає нуль доданих/видалених/змінених і один незмінний. Якщо обидва ввíди порожні — diff тривіально нульовий усюди.

Мій JSON кудись надсилається?

Ні. Обидва текстові поля залишаються у вашому браузері; diff працює в тому ж JavaScript-контексті, що й сторінка. Вкладка «Мережа» у DevTools не показує запитів при натисканні «Порівняти». Інструмент працює офлайн після кешування сторінки.

Чим це відрізняється від порядкового текстового diff?

Текстовий diff на кшталт `diff a.json b.json` працює із символами та переносами рядків: переформатуєте ті ж дані — він засвітиться. Це СТРУКТУРНИЙ diff: `{"a":1, "b":2}` та `{"b":2, "a":1}` ідентичні (нуль diff). Також не зважає на відступи, кінцеві пробіли та стилі коментарів. Використовуйте текстовий diff, коли важливе форматування; цей — коли важливі дані.