В Day.js плагин представляет собой функцию, которая принимает два аргумента: сам конструктор Day.js и опциональный объект настроек. Базовый контракт строится вокруг идеи расширения функциональности без изменения ядра библиотеки.
Плагин всегда имеет форму:
export default function pluginName(option, dayjsClass, dayjsFactory) {
// расширение API
}
В зависимости от стиля подключения аргументы могут быть представлены иначе:
option — конфигурация, переданная при подключении
плагинаdayjsClass — ссылка на конструктор Day.jsdayjsFactory — функция создания экземпляра (аналог
dayjs())Ключевой принцип: плагин не должен мутировать исходный объект непредсказуемым образом, за исключением предусмотренных точек расширения.
Подключение плагина осуществляется через метод расширения:
import dayjs from 'dayjs'
import plugin from 'dayjs/plugin/customParseFormat'
dayjs.extend(plugin)
Метод extend выполняет следующие действия:
Внутренняя логика опирается на список уже подключённых расширений, что исключает дублирование поведения.
Основной механизм расширения заключается в модификации
dayjs.prototype. Именно через него добавляются новые методы
экземпляра:
export default function relativeTimePlugin(option, dayjs, dayjsFactory) {
dayjs.prototype.fromNow = function () {
return this.from(dayjsFactory())
}
}
После подключения:
dayjs.extend(relativeTimePlugin)
dayjs().fromNow()
Типовые точки расширения:
dayjs.prototype — методы экземпляраdayjs — статические методыdayjs.factory — создание новых объектовdayjs.enhance (внутренние реализации в некоторых
сборках)Плагин может расширять сам конструктор:
export default function isTodayPlugin(option, dayjs) {
dayjs.isToday = function (date) {
return dayjs(date).isSame(dayjs(), 'day')
}
}
Использование:
dayjs.isToday('2026-01-01')
Статические методы применяются для утилитарных функций, не зависящих от конкретного экземпляра.
Экземпляр Day.js является неизменяемым объектом (immutable). Любая операция возвращает новый экземпляр.
Плагин обязан учитывать этот принцип:
dayjs.prototype.addBusinessDay = function () {
return this.add(1, 'day')
}
Важно:
Day.js предоставляет ограниченный набор внутренних механизмов для плагинов:
this.$d — оригинальный Datethis.$y, this.$M, this.$D —
компоненты датыthis.clone() — создание копии экземпляраthis.$utils — вспомогательные функции (внутренние)Пример:
dayjs.prototype.startOfWeek = function () {
const day = this.$W
return this.subtract(day, 'day')
}
Использование внутренних свойств считается допустимым, но снижает устойчивость к изменениям версии библиотеки.
Плагин может принимать опции:
export default function weekdayPlugin(option, dayjs) {
const startOfWeek = option?.startOfWeek ?? 1
dayjs.prototype.startOfWeek = function () {
return this.day(startOfWeek)
}
}
Подключение с конфигурацией:
dayjs.extend(weekdayPlugin, { startOfWeek: 0 })
Механизм опций позволяет создавать вариативные расширения без дублирования кода.
Плагин Day.js должен учитывать разные окружения:
export default function plugin(dayjs) {
dayjs.prototype.example = function () {}
}
module.exports = function plugin(dayjs) {
dayjs.prototype.example = function () {}
}
(function (global, factory) {
factory(global.dayjs)
})(this, function (dayjs) {
dayjs.prototype.example = function () {}
})
Унифицированная цель — отсутствие зависимости от среды исполнения.
Порядок extend влияет на поведение системы:
dayjs.extend(pluginA)
dayjs.extend(pluginB)
Особенности:
Пример конфликтующего поведения:
dayjs.extend(formatA)
dayjs.extend(formatB) // может переопределить format()
Day.js активно использует цепочки:
dayjs()
.add(1, 'day')
.format()
Плагин должен сохранять цепочную структуру:
dayjs.prototype.doubleAdd = function (num, unit) {
return this.add(num, unit).add(num, unit)
}
Нарушение цепочек приводит к потере согласованности API.
Некоторые плагины используют кэширование через замыкания:
export default function cachePlugin(dayjs) {
const cache = new Map()
dayjs.prototype.expensive = function () {
const key = this.valueOf()
if (cache.has(key)) return cache.get(key)
const result = this.add(10, 'day')
cache.set(key, result)
return result
}
}
Особенности:
Плагины часто расширяют форматирование:
dayjs.prototype.formatISOWeek = function () {
const week = this.isoWeek()
return `W${week}`
}
Механизм форматирования интегрируется через:
dayjs.prototype.formatСтандартная организация кода:
// зависимые функции
function helper() {}
export default function plugin(option, dayjs, dayjsFactory) {
// расширение экземпляра
dayjs.prototype.method = function () {
return this.clone()
}
// статические методы
dayjs.custom = function () {}
// вспомогательная логика
}
Разделение ответственности обычно включает:
Плагинная система Day.js имеет ряд конструктивных ограничений:
Эти особенности требуют строгой дисциплины при проектировании расширений.
Распространённые проблемы при создании плагинов:
dayjs.prototype без возврата нового
экземпляраПример проблемного кода:
dayjs.prototype.bad = function () {
this.$d.setDate(1)
return this
}
Такой подход нарушает неизменяемость экземпляра и приводит к непредсказуемым результатам.