Архитектура плагинов Day.js построена вокруг принципа минимального ядра, которое не содержит избыточной функциональности, а расширяется через подключаемые модули. Основная идея заключается в том, что каждый плагин представляет собой функцию, которая модифицирует поведение экземпляра Day.js или его прототипа.
Базовый механизм подключения реализуется через метод расширения:
dayjs.extend(plugin)
При вызове extend плагин регистрируется внутри ядра и
получает доступ к внутреннему контексту библиотеки. Это позволяет
добавлять новые методы, изменять парсинг, форматирование и поведение
вычислений дат.
Плагин в Day.js представляет собой функцию с фиксированным контрактом. Типовая форма выглядит следующим образом:
function plugin(option, dayjsClass, dayjsFactory) {
// расширение прототипа
}
Передаваемые параметры:
option — конфигурация плагина (если предусмотрена)dayjsClass — конструктор Day.js (прототип
экземпляров)dayjsFactory — основная фабрика создания объектовТакой подход обеспечивает изоляцию логики и предсказуемость расширений. Плагин не имеет скрытого состояния внутри ядра и не изменяет глобальные переменные напрямую.
Основной способ добавления функциональности — модификация прототипа Day.js. Это позволяет всем экземплярам автоматически получать новые методы.
Пример добавления метода:
function examplePlugin(option, dayjsClass) {
dayjsClass.prototype.isExample = function () {
return this.format() === 'example'
}
}
dayjs.extend(examplePlugin)
После подключения каждый объект Day.js получает метод
isExample.
Особенность архитектуры заключается в том, что расширение происходит один раз на уровне конструктора, а не на каждом экземпляре, что снижает накладные расходы.
Плагины применяются последовательно в порядке регистрации. Это влияет на итоговое состояние API.
dayjs.extend(pluginA)
dayjs.extend(pluginB)
Если оба плагина изменяют один и тот же метод, результат зависит от очередности подключения. Такая модель делает систему детерминированной, но требует контроля зависимостей между расширениями.
Некоторые плагины требуют предварительного подключения других модулей. Например, расширения работы с временными зонами опираются на базовые механизмы UTC.
Помимо прототипа экземпляров, плагины могут добавлять статические методы:
function staticPlugin(option, dayjsClass, dayjsFactory) {
dayjsFactory.customParse = function (input) {
return dayjsFactory(input)
}
}
dayjs.extend(staticPlugin)
Статические методы позволяют работать с библиотекой как с фабрикой, расширяя возможности создания и преобразования объектов.
Day.js использует иммутабельную модель: каждый вызов метода возвращает новый экземпляр. Плагины обязаны соблюдать это правило. Методы, добавляемые через плагины, не должны изменять текущий объект.
dayjs().add(1, 'day') // возвращает новый объект
Плагин должен сохранять эту семантику, иначе нарушается предсказуемость цепочек вызовов.
Плагин UTC изменяет поведение создания объектов, добавляя поддержку координированного времени:
Плагин advancedFormat добавляет дополнительные токены форматирования:
Плагин relativeTime вводит метод вычисления разницы между датами в человекочитаемом виде:
Реализация основана на сравнении временных меток и наборе правил округления.
Каждый плагин действует в рамках общего пространства Day.js, но не имеет собственного изолированного контекста. Это означает:
Для минимизации конфликтов используется соглашение о неймспейсах методов и строгая модульность.
Плагины могут зависеть друг от друга, формируя цепочки расширений. При этом отсутствует встроенный менеджер зависимостей. Управление связями осуществляется вручную через порядок подключения.
Некоторые плагины проверяют наличие других расширений через наличие методов:
if (!dayjs().utc) {
throw new Error('UTC plugin required')
}
Модульная структура Day.js позволяет подключать только необходимые плагины, что положительно влияет на размер итогового бандла. Каждый плагин является независимым модулем, импортируемым отдельно.
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
dayjs.extend(utc)
Такой подход снижает количество неиспользуемого кода и улучшает производительность загрузки.
Часть плагинов работает не только с прототипом, но и с внутренними функциями парсинга:
Это достигается через модификацию внутренних фабрик, передаваемых в плагин как аргументы.
Несмотря на гибкость, модель имеет ряд ограничений:
Эти ограничения компенсируются простотой реализации и предсказуемостью поведения системы.