Breaking changes

Breaking changes — это изменения в библиотеке, нарушающие обратную совместимость. После обновления до новой версии код, написанный для предыдущих версий, может перестать работать или работать некорректно.

Для библиотек пользовательского интерфейса, подобных Muuri, breaking changes чаще всего касаются:

  • изменения API методов
  • переименования параметров
  • изменения поведения методов
  • изменения структуры данных
  • изменения системы событий
  • изменений механизма позиционирования элементов
  • удаления устаревших возможностей

В проектах с динамическими сетками такие изменения особенно критичны, поскольку Muuri тесно связан с:

  • DOM-структурой
  • системой drag-and-drop
  • анимациями
  • фильтрацией и сортировкой элементов

При обновлении версии библиотеки требуется внимательно анализировать release notes и адаптировать код.


Основные категории breaking changes

Breaking changes в Muuri обычно делятся на несколько категорий.

1. Изменение сигнатуры методов

Методы могут менять:

  • количество аргументов
  • порядок аргументов
  • формат передаваемых данных

Пример (условный)

Старая версия:

grid.add(element, options);

Новая версия:

grid.add([element], options);

Теперь элемент должен передаваться в массиве, иначе метод не выполнится корректно.


2. Изменение возвращаемых значений

Методы могут начать возвращать другие типы данных.

Старая версия

const item = grid.add(element);

Метод возвращал объект Item.

Новая версия

const items = grid.add(element);

Метод возвращает массив Item.

Код, ожидающий один объект, будет работать неправильно.


3. Удаление устаревших методов

Со временем библиотека избавляется от устаревших функций.

Например, метод мог быть удалён полностью.

Старый код:

grid.refresh();

Новая версия может использовать:

grid.refreshItems().layout();

В этом случае:

  • обновление элементов
  • перерасчёт layout

разделены на разные операции.


4. Изменение системы событий

Muuri активно использует событийную модель. Breaking changes могут касаться:

  • названий событий
  • структуры передаваемых аргументов
  • порядка вызова

Пример.

Старый вариант:

grid.on('move', function(data) {
  console.log(data.item);
});

Новая версия может изменить структуру:

grid.on('move', function(event) {
  console.log(event.item);
});

В некоторых версиях параметры передаются несколькими аргументами, а не одним объектом.


5. Изменения в системе drag-and-drop

Muuri включает мощную систему перетаскивания элементов. Breaking changes часто затрагивают именно эту часть.

Могут изменяться:

  • названия опций
  • способ инициализации
  • формат callback-функций

Старая конфигурация

new Muuri('.grid', {
  dragEnabled: true
});

Новая версия

new Muuri('.grid', {
  dragEnabled: true,
  dragSort: true
});

Если ранее dragSort включался автоматически, новая версия может требовать его явного указания.


Breaking changes в конфигурации Grid

Объект конфигурации при создании grid может меняться.

Изменение структуры опций

Некоторые опции могут перемещаться в новые вложенные объекты.

Старая версия

new Muuri('.grid', {
  dragEnabled: true,
  dragStartPredicate: function(item, event) {
    return true;
  }
});

Новая версия

new Muuri('.grid', {
  dragEnabled: true,
  dragStartPredicate: {
    distance: 5,
    delay: 0
  }
});

Callback заменён на объект конфигурации.


Изменение значений по умолчанию

Даже без изменения API поведение библиотеки может измениться.

Например:

  • время анимации
  • easing
  • порядок сортировки
  • алгоритм layout

Пример

В старой версии:

layoutDuration = 300

В новой:

layoutDuration = 500

Это влияет на плавность анимаций и тайминги интерфейса.


Breaking changes в системе Item

Muuri оперирует объектами Item, представляющими элементы сетки.

Изменения могут касаться:

  • методов Item
  • доступа к DOM-элементу
  • внутреннего состояния

Изменение метода получения DOM

Старый код:

item.getElement();

Новая версия может использовать:

item.getElement();

Но структура самого элемента могла измениться.

Например:

item.getElement().querySelector('.content');

может перестать работать, если библиотека изменила структуру wrapper-элементов.


Изменение методов позиционирования

Muuri управляет позициями через layout engine.

Старый код:

item._left
item._top

Использование внутренних свойств может перестать работать после обновления.

Вместо этого необходимо использовать публичные методы:

item.getPosition();

Breaking changes в сортировке

Muuri поддерживает мощную систему сортировки.

Изменения могут затронуть:

  • функцию сравнения
  • формат возвращаемых значений
  • структуру данных элементов

Старая версия

grid.sort(function(a, b) {
  return a.getElement().dataset.order - b.getElement().dataset.order;
});

Новая версия

Иногда сортировка может работать через ключи:

grid.sort('order');

При этом атрибут должен существовать:

<div class="item" data-order="10"></div>

Breaking changes в фильтрации

Фильтрация элементов выполняется через grid.filter().

Изменения могут касаться формата callback.

Старая версия

grid.filter(function(item) {
  return item.getElement().classList.contains('active');
});

Новая версия

Callback может получать дополнительные параметры:

grid.filter(function(item, index) {
  return item.getElement().classList.contains('active');
});

Код, зависящий от аргументов, может требовать корректировки.


Breaking changes в layout-системе

Muuri использует собственный алгоритм размещения элементов.

Изменения могут включать:

  • новый алгоритм packing
  • изменение расчёта gutter
  • изменение поведения при resize

Изменение опции layout

Старый вариант:

layout: {
  fillGaps: true
}

Новый вариант может иметь дополнительные параметры:

layout: {
  fillGaps: true,
  horizontal: false,
  alignRight: false
}

Если проект зависел от старых значений по умолчанию, layout может начать вести себя иначе.


Breaking changes в анимациях

Muuri активно использует CSS-transform и transitions.

Изменения могут касаться:

  • timing functions
  • структуры CSS классов
  • поведения при layout

Изменение CSS-классов

Старый код мог зависеть от внутренних классов:

.muuri-item-dragging

После обновления класс может измениться:

.muuri-item--dragging

Кастомные стили перестают применяться.


Breaking changes при работе с DOM

Muuri создаёт дополнительные DOM-обёртки.

Обновления могут изменить структуру элементов.

Старый DOM

.grid
  .item
    .content

Новый DOM

.grid
  .muuri-item
    .muuri-item-content

Скрипты, обращающиеся к дочерним элементам напрямую, могут перестать работать.


Breaking changes при работе с drag events

Drag события в Muuri включают:

  • dragInit
  • dragStart
  • dragMove
  • dragEnd
  • dragReleaseStart
  • dragReleaseEnd

Изменения могут касаться параметров callback.

Старый вариант

grid.on('dragEnd', function(item) {
  console.log(item);
});

Новый вариант

grid.on('dragEnd', function(item, event) {
  console.log(event);
});

Breaking changes в API destroy

Удаление grid может измениться.

Старая версия

grid.destroy();

Новая версия

grid.destroy(true);

Параметр может означать:

  • удаление DOM
  • сохранение DOM

Если параметр не передан, поведение может отличаться.


Breaking changes при работе с несколькими grid

Muuri поддерживает перетаскивание элементов между несколькими сетками.

Конфигурация может измениться.

Старая версия

dragSort: true

Новая версия

dragSort: function() {
  return [grid1, grid2];
}

Теперь необходимо явно указать сетки.


Стратегии миграции при breaking changes

При обновлении Muuri применяется несколько стратегий.

1. Проверка release notes

Каждая версия библиотеки публикует:

  • список изменений
  • удалённые функции
  • новые параметры

2. Поиск deprecated API

Если код использует устаревшие методы, необходимо заменить их на новые.


3. Тестирование drag-системы

Drag-and-drop является наиболее чувствительной частью.

Проверяются:

  • начало drag
  • перенос между grid
  • drop
  • анимации

4. Проверка фильтрации и сортировки

Особенно важно проверить:

  • порядок элементов
  • корректность dataset-значений
  • поведение при обновлении данных

5. Проверка кастомных CSS

Любые стили, зависящие от внутренних классов Muuri, должны быть проверены после обновления.


Минимизация проблем при будущих обновлениях

Существует несколько практик, уменьшающих влияние breaking changes.

Не использовать внутренние свойства

Нельзя обращаться к полям вида:

item._width
item._left
item._height

Это внутренний API, который может измениться.


Использовать только публичные методы

Например:

item.getWidth()
item.getHeight()
item.getPosition()

Изолировать код интеграции

Логику Muuri лучше размещать в отдельном модуле:

gridManager.js

Это упрощает миграцию.


Не зависеть от внутренней структуры DOM

Лучше оперировать:

  • item.getElement()
  • dataset-атрибутами
  • внешними wrapper-элементами

Фиксация версии библиотеки

Для production-проектов используется фиксированная версия:

muuri@0.9.5

Автоматическое обновление может привести к неожиданным breaking changes.


Типичный пример миграции

Старый код:

var grid = new Muuri('.grid', {
  dragEnabled: true
});

grid.add(document.createElement('div'));

После breaking changes:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  dragSort: true
});

grid.add([document.createElement('div')]);

Изменения:

  • добавлен dragSort
  • элемент передаётся массивом
  • используется const

Наиболее чувствительные части Muuri к breaking changes

Практика показывает, что чаще всего изменения затрагивают:

1. drag-and-drop

  • dragSort
  • dragStartPredicate
  • drag events

2. layout engine

  • fillGaps
  • horizontal layout
  • alignment

3. методы работы с элементами

  • add
  • remove
  • move
  • sort

4. события grid

  • layoutStart
  • layoutEnd
  • move
  • dragReleaseEnd

Практические признаки breaking changes

После обновления Muuri проблемы могут проявляться следующим образом:

  • элементы накладываются друг на друга
  • drag перестаёт работать
  • фильтрация работает некорректно
  • анимации исчезают
  • сортировка выполняется неправильно
  • события не вызываются

Во всех этих случаях необходимо проверить соответствие кода новому API библиотеки.