Обновление версии библиотеки связано не только с получением новых возможностей. Между релизами Choices.js исправляются ошибки рендеринга, меняется архитектура внутреннего состояния, оптимизируется работа поиска, улучшается поддержка мобильных браузеров и устраняются проблемы совместимости с современными сборщиками.
На практике обновление обычно требуется в следующих случаях:
Перед обновлением необходимо определить используемую версию библиотеки.
{
"dependencies": {
"choices.js": "^9.0.1"
}
}
npm list choices.js
console.log(Choices);
В старых версиях объект библиотеки мог экспортироваться иначе, особенно при использовании UMD-сборки.
В разных версиях менялись:
shadowRoot;Даже минорное обновление иногда приводит к несовместимости интерфейсов.
import Choices from 'choices.js/assets/scripts/choices';
import Choices from 'choices.js';
Новые версии предоставляют корректный entry point для ESM.
import 'choices.js/assets/styles/css/choices.css';
import 'choices.js/public/assets/styles/choices.css';
В некоторых версиях структура каталогов изменялась несколько раз,
поэтому после обновления важно проверить путь внутри
node_modules.
<div class="choices__inner"></div>
В новых релизах могли появляться:
<div class="choices__list choices__list--single"></div>
или дополнительные служебные контейнеры.
Если проект содержит кастомные стили:
.choices__inner {
height: 40px;
}
то после обновления могут возникнуть:
После обновления необходимо проверить:
В ранних версиях события могли передавать разные структуры объекта.
element.addEventListener('addItem', (event) => {
console.log(event.detail);
});
Старые версии:
event.detail.value
Новые версии:
event.detail.label
event.detail.value
event.detail.customProperties
После обновления необходимо проверить все обработчики.
element.addEventListener('choice', function(event) {
send(event.detail.choice.id);
});
После обновления:
choice может отсутствовать;Особенно часто изменения касались:
setChoicesclearStoreclearChoicessetValueremoveActiveItemschoices.setChoices(data, 'value', 'label', true);
choices.setChoices(data, 'value', 'label', false);
В некоторых версиях изменялось поведение последнего параметра.
Это приводило к неожиданной очистке списка.
choices.setChoices(async () => {
return fetchData();
});
choices.setChoices(async () => {
const data = await fetchData();
return data;
});
Некоторые версии меняли обработку Promise и внутренний lifecycle.
Частая проблема:
choices.setChoices(newData);
choices.setChoices(newData);
После обновления библиотека могла перестать автоматически очищать store.
choices.clearChoices();
choices.setChoices(newData);
choices.destroy();
Экземпляр удалял DOM-обёртку частично.
В новых версиях:
new Choices(element);
new Choices(element);
После обновления подобный код чаще приводит к:
if (instance) {
instance.destroy();
}
instance = new Choices(element);
Choices.js не зависит от jQuery, однако старые проекты часто используют смешанный подход.
$('#select').html(options);
После обновления Choices.js внутренний store может не синхронизироваться с DOM.
choices.clearChoices();
choices.setChoices(data, 'value', 'label', true);
Поиск выполнялся проще и медленнее.
Новые версии:
Особенно важно тестировать:
placeholder: true
В некоторых версиях потребовалось:
placeholder: true,
placeholderValue: 'Выберите значение'
<option value=""></option>
Пустой option мог:
После обновления возможны ситуации:
form.checkValidity();
Необходимо тестировать нативную HTML-валидацию отдельно.
Использовали:
Основной акцент делается на:
Module parse failed
Старый конфиг Webpack не обрабатывает современные модули.
Обновление:
В Vite обычно проблемы связаны с:
Choices.js использует DOM API.
Поэтому код:
new Choices(element);
не должен выполняться на сервере.
if (typeof window !== 'undefined') {
new Choices(element);
}
React повторно рендерит select.
Choices.js при этом:
useEffect(() => {
const instance = new Choices(ref.current);
return () => {
instance.destroy();
};
}, []);
Во Vue особенно важно:
beforeUnmount;После обновления могут появляться:
ngAfterViewInit() {
this.choices = new Choices(this.element.nativeElement);
}
ngOnDestroy() {
this.choices.destroy();
}
Новые версии улучшали:
Проверяются:
После обновления необходимо тестировать:
callbackOnCreateTemplates: function(template) {
return {};
}
Могли измениться:
В новых версиях могли усиливаться механизмы sanitization.
allowHTML: true
После обновления:
Плохой подход:
npm install choices.js@latest
Последовательное обновление:
8.x → 9.x → 10.x → 11.x
Так проще выявлять несовместимости.
При обновлении необходимо анализировать:
Перед обновлением желательно подготовить:
expect(select.value).toBe('2');
expect(handler).toHaveBeenCalled();
expect(document.querySelector('.choices')).not.toBeNull();
instance.destroy();
instance.destroy();
После обновления некоторые версии перестали игнорировать повторный вызов.
select.innerHTML = '';
Choices.js может потерять внутреннее состояние.
choices.setChoices(...);
select.appendChild(...);
Необходимо использовать единый источник управления.
После обновления важно протестировать:
На мобильных устройствах после обновления возможны:
Choices.js активно работает с DOM и событиями.
После обновления следует проверять:
Особенно полезны:
В крупных проектах обновление часто внедряется постепенно.
const useNewChoices = true;
if (useNewChoices) {
initNewChoices();
} else {
initOldChoices();
}
Иногда удобно временно запускать две версии:
choices-v9
choices-v11
Это помогает сравнить:
Во многих версиях старые методы сначала помечаются как deprecated.
Метод работает:
choices.someOldMethod();
но в следующем major-релизе полностью удаляется.
Наиболее стабильный подход: