Breaking changes — изменения, нарушающие обратную совместимость. При обновлении библиотеки важно знать, что именно изменилось, чтобы не потратить время на отладку регрессий.
Одно из ключевых изменений между версиями — стандартизация возвращаемого типа функции локали.
Старый формат (некоторые ранние версии):
// Возвращала только строку или массив строк переменной длины
register('old', (n, i) => 'давно');
register('old', (n, i) => ['давно', 'скоро', 'только что']);
Новый формат (3.x, 4.x — обязательно):
// Строго кортеж из двух строк: [прошлое, будущее]
register('new', (n, i) => ['давно', 'скоро']);
Код с неверным возвращаемым типом молча работает некорректно — без исключений.
До 3.x:
import timeago from 'timeago.js';
const { format, render, cancel, register } = timeago;
С 3.x — именованные экспорты:
import { format, render, cancel, register } from 'timeago.js';
Дефолтный импорт может не работать в ESM-режиме. Старый код с деструктуризацией из default требует обновления.
До 3.x:
const ru = require('timeago.js/locales/ru'); // Старый путь
С 3.x:
import ru from 'timeago.js/esm/lang/ru'; // ESM
const ru = require('timeago.js/lib/lang/ru'); // CJS
В 3.x появились официальные типы. Если проект использовал
@types/timeago.js (сообщественный пакет), возможны
конфликты:
npm uninstall @types/timeago.js # Удалить — типы встроены в пакет
Тип FormatOptions стал официальным и может отличаться от
сообщественных деклараций.
В некоторых версиях format с невалидной датой:
Поведение нестабильно между версиями. Самостоятельная проверка на валидность обязательна:
const d = new Date(input);
const result = isNaN(d.getTime()) ? fallback : format(d, locale);
В ранних версиях библиотека могла добавлять
window.timeago:
<!-- Старый CDN -->
<script src="timeago.js"></script>
<script>
timeago.format(date); // глобальная переменная
</script>
Современные версии используют модульную систему. CDN-версия может не создавать глобал или создавать с другим именем.
В некоторых версиях:
format(date, locale, relativeDate); // Третий аргумент — дата, не объект
В текущей версии:
format(date, locale, { relativeDate: date }); // Третий аргумент — объект опций
# Сравнить версии
npm show timeago.js versions --json
# Обновить и сразу запустить тесты
npm update timeago.js && npm test
Если тесты покрывают вызовы format, render,
cancel — регрессия будет поймана автоматически.
# Просмотреть историю изменений на GitHub
# github.com/hustcc/timeago.js/blob/master/CHANGELOG.md
# Или через npm
npm show timeago.js changelog
// Перед обновлением — зафиксировать текущее поведение
describe('timeago.js behavior contract', () => {
const NOW = new Date('2025-06-01T12:00:00Z').getTime();
beforeAll(() => { jest.setSystemTime(NOW); });
it('format возвращает строку для Date', () => {
expect(typeof format(new Date(NOW - 60_000), 'ru')).toBe('string');
});
it('format возвращает непустую строку', () => {
expect(format(new Date(NOW - 60_000), 'ru').length).toBeGreaterThan(0);
});
it('render не бросает для валидного элемента', () => {
const el = document.createElement('time');
el.setAttribute('datetime', new Date(NOW - 60_000).toISOString());
document.body.appendChild(el);
expect(() => render(el, 'ru')).not.toThrow();
cancel(el);
document.body.removeChild(el);
});
});
Запустить до и после обновления — если тесты проходят в обоих случаях, обновление безопасно.
npm ci.