Cleave.js распространяется в нескольких форматах, ориентированных на разные сценарии сборки: CommonJS, ES Modules и UMD. Выбор формата напрямую влияет на то, как библиотека будет интегрироваться в проект и как сборщик сможет выполнять оптимизации.
Основные форматы:
<script> без сборкиESM-версия обеспечивает корректный tree-shaking, что особенно важно при использовании Vite, Rollup и современных конфигураций Webpack.
Webpack поддерживает оба основных формата, но оптимальная интеграция достигается через ESM-импорт.
npm install cleave.js
import Cleave from 'cleave.js';
import 'cleave.js/dist/addons/cleave-phone.i18n';
При использовании Webpack 5 модуль будет автоматически включён в граф
зависимостей. Важно учитывать, что некоторые версии Cleave.js могут
экспортировать как default, так и named exports, поэтому конфигурация
esModuleInterop в TypeScript может влиять на поведение
импорта.
const input = document.querySelector('#phone');
const cleave = new Cleave(input, {
phone: true,
phoneRegionCode: 'US'
});
Для корректной оптимизации важно учитывать поле
sideEffects:
{
"sideEffects": false
}
Однако для Cleave.js это не всегда безопасно, так как библиотека модифицирует DOM. В Webpack рекомендуется не форсировать агрессивное удаление модулей без проверки.
Vite использует ESBuild для дев-сервера и Rollup для production-сборки, что делает работу с Cleave.js более предсказуемой.
npm install cleave.js
import Cleave from 'cleave.js';
Vite автоматически оптимизирует зависимости, поэтому дополнительная конфигурация обычно не требуется.
let cleave;
export function init() {
const input = document.querySelector('#card');
cleave = new Cleave(input, {
creditCard: true
});
}
export function destroy() {
if (cleave) {
cleave.destroy();
cleave = null;
}
}
Rollup чаще всего используется при создании библиотек, где Cleave.js подключается как внешняя зависимость.
export default {
input: 'src/index.js',
output: {
format: 'esm',
file: 'dist/bundle.js'
},
external: ['cleave.js']
};
Такой подход предотвращает дублирование кода библиотеки в итоговом бандле.
import resolve from '@rollup/plugin-node-resolve';
export default {
plugins: [
resolve()
]
};
Parcel автоматически обрабатывает зависимости, включая Cleave.js, без дополнительной настройки.
import Cleave from 'cleave.js';
new Cleave('#date', {
date: true,
datePattern: ['d', 'm', 'Y']
});
Особенности Parcel:
При использовании TypeScript могут возникать расхождения типов из-за различий между CommonJS и ESM экспортом Cleave.js.
import Cleave from 'cleave.js';
const input = document.getElementById('price') as HTMLInputElement;
new Cleave(input, {
numeral: true,
numeralThousandsGroupStyle: 'thousand'
});
При отсутствии esModuleInterop:
import * as Cleave from 'cleave.js';
В таком случае доступ к конструктору осуществляется через:
const cleave = new (Cleave as any).default(input, options);
При использовании Babel важно учитывать, что Cleave.js не требует трансформации синтаксиса, но может зависеть от настроек модулей.
{
"presets": [
["@babel/preset-env", {
"modules": "auto"
}]
]
}
Неправильная конфигурация может привести к:
Cleave.js ориентирован на работу с DOM, поэтому при серверном рендеринге требуется изоляция клиентской логики.
if (typeof window !== 'undefined') {
const Cleave = require('cleave.js');
new Cleave('#ssr-input', {
numeral: true
});
}
В SSR-приложениях (Next.js, Nuxt) инициализация выполняется только на клиенте:
useEffect(() => {
const Cleave = require('cleave.js');
const instance = new Cleave(inputRef.current, {
phone: true
});
return () => instance.destroy();
}, []);
В монорепозиториях (pnpm, yarn workspaces) важно избегать дублирования зависимостей Cleave.js.
resolve: {
alias: {
'cleave.js': require.resolve('cleave.js')
}
}
При использовании сборщиков критично контролировать момент загрузки Cleave.js.
async function loadMask() {
const { default: Cleave } = await import('cleave.js');
new Cleave('#dynamic', {
numeral: true
});
}
Webpack автоматически выделяет библиотеку в отдельный chunk при динамическом импорте, снижая первоначальный размер бандла.
Ошибки вида:
Cleave is not a constructordefault is undefinedПричина — неправильная интерпретация экспорта.
При повторной инициализации без destroy() возникают
конфликтующие обработчики событий.
Cleave.js активно работает с DOM, поэтому удаление модулей сборщиком может приводить к некорректному поведению.
Hot Module Replacement не всегда корректно пересоздаёт DOM-инстансы, требуется ручной контроль жизненного цикла.
Использование Cleave.js в современных системах сборки строится вокруг нескольких ключевых принципов: