Jsondiffpatch — сравнение и патчинг JSON-объектов
Библиотека для глубокого сравнения JavaScript-объектов, создания компактных дельт (описаний изменений) и их применения (патч/анпатч). Подходит для браузера и Node.js (ESM), размер ~16 KB gzip.
Возможности
- Глубокое сравнение — рекурсивно обходит вложенные объекты и массивы.
- Умное сравнение массивов — использует алгоритм LCS (самая длинная общая подпоследовательность). Для сопоставления одинаковых объектов внутри массива обязательно укажите функцию
objectHash, иначе сравнивает по позициям.
- Текстовые диффы — для длинных строк (по умолчанию от 60 символов) использует
google-diff-match-patch (на уровне символов).
- Обратимость — дельту можно инвертировать (
reverse) и откатить изменения (unpatch).
- Форматы вывода: компактный JSON (свой формат), визуальный HTML, аннотированный JSON, JSON Patch (RFC 6902), цветной вывод в консоль.
- Плагины — расширяйте логику через механизм фильтров и конвейеров (pipes & filters).
Установка
NPM
npm install jsondiffpatch
Импорт в проекте:
import * as jsondiffpatch from 'jsondiffpatch';
Браузер
Используйте CDN: esm.sh или Skypack.
Быстрый старт
Базовое сравнение объектов
import * as jsondiffpatch from 'jsondiffpatch';
const country = {
name: 'Argentina',
capital: 'Buenos Aires',
independence: new Date(1816, 6, 9),
};
const country2 = JSON.parse(JSON.stringify(country), jsondiffpatch.dateReviver);
country2.name = 'Republica Argentina';
country2.population = 41324992;
delete country2.capital;
const delta = jsondiffpatch.diff(country, country2);
// delta: { name: ['Argentina', 'Republica Argentina'], population: ['41324992'], capital: ['Buenos Aires', 0, 0] }
// Применить изменения к оригиналу
jsondiffpatch.patch(country, delta);
// country теперь равен country2
// Обратить дельту
const reverseDelta = jsondiffpatch.reverse(delta);
jsondiffpatch.unpatch(country2, delta);
// country2 вернулся к исходному состоянию
Сравнение массивов (сопоставление по свойству)
const country = {
name: 'Argentina',
cities: [
{ name: 'Buenos Aires', population: 13028000 },
{ name: 'Cordoba', population: 1430023 },
],
};
const country2 = JSON.parse(JSON.stringify(country));
// Изменения: удаляем Cordoba, добавляем La Plata
country.cities.splice(1, 1);
country.cities.push({ name: 'La Plata' });
// Создаём экземпляр с objectHash, чтобы сопоставлять города по имени
const diffpatcher = jsondiffpatch.create({
objectHash: (obj) => obj.name,
});
const delta = diffpatcher.diff(country, country2);
// delta.cities содержит информацию о вставке, удалении и перемещениях
Конфигурация
| Параметр |
Тип |
По умолчанию |
Описание |
objectHash |
function |
=== |
Функция для сопоставления объектов в массивах. Должна возвращать уникальный идентификатор (например, obj.id) |
arrays.detectMove |
boolean |
true |
Обнаруживать перемещение элементов внутри массива (иначе — удаление + вставка) |
arrays.includeValueOnMove |
boolean |
false |
Включать значение перемещённого элемента в дельту |
textDiff.diffMatchPatch |
object |
— |
Экземпляр diff_match_patch (из @dmsnell/diff-match-patch). Нужен для текстовых диффов |
textDiff.minLength |
number |
60 |
Минимальная длина строки для использования текстового алгоритма |
propertyFilter |
function |
— |
Отфильтровывает свойства, которые не нужно сравнивать (например, начинающиеся с $) |
cloneDiffValues |
boolean/function |
false |
Клонировать значения в дельте, чтобы избежать ссылок на левый/правый объект |
omitRemovedValues |
boolean |
false |
Не включать в дельту старые значения (если не нужна операция unpatch) — для более компактных дельт |
Текстовые диффы
Если нужен подробный текстовый дифф (на уровне символов), установите опцию textDiff.diffMatchPatch:
import { diff_match_patch } from '@dmsnell/diff-match-patch';
const instance = jsondiffpatch.create({
textDiff: { diffMatchPatch: diff_match_patch, minLength: 20 },
});
Либо импортируйте предсобранную версию: import jsondiffpatch from 'jsondiffpatch/with-text-diffs'.
Форматеры выводов
Консоль (цветной вывод)
npx jsondiffpatch left.json right.json
HTML (визуальный дифф)
Подключите стили и скрипты (пример для ESM):
<link rel="stylesheet" href="https://esm.sh/jsondiffpatch@0.6.0/lib/formatters/styles/html.css">
<script type="module">
import * as jsondiffpatch from 'https://esm.sh/jsondiffpatch@0.6.0';
import * as htmlFormatter from 'https://esm.sh/jsondiffpatch@0.6.0/formatters/html';
const delta = jsondiffpatch.diff({ a: 3 }, { a: 5 });
document.getElementById('visual').innerHTML = htmlFormatter.format(delta, left);
</script>
JSON Patch (RFC 6902)
Библиотека может генерировать и применять патчи в этом формате.
Дополнительно
Лицензия
MIT. Автор: Benjamín Eidelman.
Комментарии
Комментариев пока нет. Будьте первым.