Библиотека date-fns распространяется как набор модульных функций, ориентированных на ESM и CommonJS, что делает её удобной для интеграции с современными сборщиками. При работе с бандлерами ключевым становится корректная настройка tree-shaking, обработка локалей и выбор формата импортов.
Основная особенность архитектуры заключается в том, что каждая функция экспортируется отдельно. Это позволяет системам сборки удалять неиспользуемый код, но только при условии правильной конфигурации webpack или rollup.
Современные версии date-fns ориентированы на ES Modules:
import { format, addDays } from 'date-fns';
Такой импорт позволяет бандлерам выполнять статический анализ зависимостей.
CommonJS-вариант:
const { format, addDays } = require('date-fns');
При использовании CommonJS tree-shaking часто работает хуже, особенно в webpack без дополнительной настройки sideEffects.
Корректная работа tree-shaking требует включённого production mode:
const path = require('path');
module.exports = {
mode: 'production',
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
Важные параметры:
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
Параметр sideEffects: false критичен для библиотек вроде
date-fns, где каждый модуль является чистым.
webpack по умолчанию поддерживает поле module в
package.json, но в некоторых случаях полезно явно указать:
resolve: {
mainFields: ['module', 'main']
}
Это позволяет приоритизировать ESM-версию библиотеки.
date-fns содержит локали, которые могут значительно увеличивать размер бандла:
import { format } from 'date-fns';
import { ru } from 'date-fns/locale';
Чтобы избежать подтягивания всех локалей, необходимо импортировать их напрямую, а не через индексные файлы.
Иногда применяется ограничение доступных локалей:
module.exports = {
resolve: {
alias: {
'date-fns/locale': 'date-fns/locale/ru'
}
}
};
Это позволяет принудительно ограничить набор языков.
Rollup изначально ориентирован на ESM и обеспечивает более агрессивный tree-shaking.
Базовая конфигурация:
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
resolve(),
commonjs()
]
};
rollup выполняет статический анализ модулей на этапе сборки и удаляет неиспользуемые экспорты без дополнительных настроек, если зависимости написаны в ESM-формате.
date-fns хорошо подходит для такого подхода, поскольку каждая функция представляет собой независимый модуль.
date-fns поддерживает несколько форматов:
Выбор формата влияет на итоговый размер бандла и эффективность tree-shaking.
При неправильной настройке сборщика могут появляться дубликаты функций:
import format from 'date-fns/format';
import addDays from 'date-fns/addDays';
Такой подход иногда предпочтительнее в webpack-сборках, где ESM анализ ограничен.
В rollup достаточно:
import { format, addDays } from 'date-fns';
Важнейший аспект оптимизации — корректное определение побочных эффектов.
date-fns не выполняет глобальных изменений состояния, поэтому может считаться полностью чистой библиотекой:
{
"sideEffects": false
}
Это позволяет сборщикам безопасно удалять неиспользуемые части дерева зависимостей.
Основные факторы, влияющие на размер:
Оптимальная стратегия — точечные импорты:
import format from 'date-fns/format';
import parseISO from 'date-fns/parseISO';
В старых версиях webpack может потребоваться настройка транспиляции:
module.exports = {
module: {
rules: [
{
test: /\.m?js$/,
resolve: {
fullySpecified: false
}
}
]
}
};
Это предотвращает ошибки резолва ESM-путей.
webpack автоматически поддерживает динамические импорты:
import('date-fns/format').then(({ default: format }) => {
console.log(format(new Date(), 'yyyy-MM-dd'));
});
rollup использует аналогичный механизм через динамический
import() при соответствующем output формате.
При создании собственной библиотеки поверх date-fns важно сохранять ESM-совместимость:
export { format } from 'date-fns/format';
export { addDays } from 'date-fns/addDays';
Это позволяет downstream-сборщикам корректно выполнять tree-shaking.
import * as df from 'date-fns';
Такой импорт блокирует tree-shaking и приводит к включению всех модулей.
Импорт через индекс:
import { ru } from 'date-fns/locale';
может подтянуть лишние данные при неправильной сборке, если бандлер не оптимизирует ESM-дерево.
При смешивании форматов возможны дубли и увеличение размера bundle,
особенно в webpack без корректного mainFields.