При использовании Rollup для сборки JavaScript-библиотек, таких как Tom Select, ключевая цель заключается в создании нескольких форматов дистрибутива, корректной работе с зависимостями и минимизации побочных эффектов. Tom Sel ect как компонент селектора требует аккуратной обработки модулей, стилей и плагинов, особенно при поддержке ESM и UMD.
Типичная конфигурация Rollup для библиотеки включает входную точку, список внешних зависимостей и набор плагинов для обработки TypeScript, Babel и стилей.
import resolve fr om '@rollup/plugin-node-resolve'
import commonjs from '@rollup/plugin-commonjs'
import babel from '@rollup/plugin-babel'
import terser from '@rollup/plugin-terser'
import postcss from 'rollup-plugin-postcss'
import typescript from '@rollup/plugin-typescript'
import pkg from './package.json' assert { type: 'json' }
const external = [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {})
]
export default [
{
input: 'src/index.ts',
output: [
{
file: pkg.module,
format: 'esm',
sourcemap: true
},
{
file: pkg.main,
format: 'cjs',
sourcemap: true
}
],
external,
plugins: [
resolve(),
commonjs(),
typescript(),
postcss({
extract: true,
minimize: true
}),
babel({
babelHelpers: 'bundled',
extensions: ['.js', '.ts']
}),
terser()
]
}
]
Для библиотеки уровня Tom Select критично исключать зависимости из бандла. Это предотвращает дублирование кода и конфликты версий в приложениях, которые используют библиотеку.
const external = (id) => {
return /^lodash/.test(id) || /^@popperjs/.test(id)
}
Такой подход позволяет гибко исключать целые группы пакетов, особенно если библиотека использует вспомогательные утилиты.
Rollup позволяет собирать несколько форматов одновременно, что важно для совместимости с различными экосистемами.
output: [
{
file: 'dist/tom-select.esm.js',
format: 'esm',
sourcemap: true
},
{
file: 'dist/tom-select.cjs.js',
format: 'cjs',
exports: 'named'
}
]
Tom Select часто расширяется типами, поэтому TypeScript является важной частью pipeline.
{
"compilerOptions": {
"target": "ES2019",
"module": "ESNext",
"declaration": true,
"outDir": "dist/types",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}
typescript({
tsconfig: './tsconfig.json',
declaration: true
})
Важно разделять генерацию .d.ts и JavaScript, чтобы
избежать дублирования и конфликтов типов.
Tom Select включает стили, которые должны корректно попадать в
сборку. Rollup не обрабатывает CSS по умолчанию, поэтому используется
postcss.
postcss({
extract: 'tom-select.css',
minimize: true,
sourceMap: true
})
Такой подход позволяет:
<link>Для production-сборки применяется terser, который уменьшает размер итогового пакета.
terser({
format: {
comments: false
}
})
Оптимизация особенно важна для компонентов UI, где размер библиотеки напрямую влияет на время загрузки страницы.
В реальных проектах Rollup-конфигурация часто разделяется на режимы.
const dev = {
sourcemap: true,
plugins: [
resolve(),
commonjs(),
typescript()
]
}
const prod = {
sourcemap: false,
plugins: [
resolve(),
commonjs(),
typescript(),
terser()
]
}
Разделение позволяет ускорить разработку и сохранять производительность в продакшене.
Tom Select расширяется через плагины, которые также должны учитываться в сборке.
export default function loadPlugin(name) {
return import(`./plugins/${name}.ts`)
}
Rollup требует явного указания динамических импортов, иначе они могут быть исключены из бандла.
plugins: [
{
name: 'fix-dynamic-imports',
resolveId(id) {
if (id.includes('plugins/')) {
return id
}
}
}
]
Некоторые зависимости Tom Select могут поставляться в формате CommonJS, что требует дополнительной трансформации.
commonjs({
include: /node_modules/
})
Без этого шага возможны ошибки вида
undefined exports.
Плагин node-resolve обеспечивает корректное разрешение
модулей из node_modules.
resolve({
browser: true,
dedupe: ['tom-select']
})
Опция dedupe предотвращает дублирование библиотек при
монорепозиториях.
Для подключения через <script> используется
UMD-формат.
{
file: 'dist/tom-select.umd.js',
format: 'umd',
name: 'TomSelect',
globals: {
lodash: '_'
}
}
UMD позволяет использовать библиотеку без модульного загрузчика.
Sourcemaps необходимы для отладки и анализа ошибок в production.
output: {
sourcemap: true
}
В некоторых случаях применяется скрытая генерация:
sourcemap: 'hidden'
Rollup поддерживает incremental rebuild через watch режим.
watch: {
include: 'src/**',
clearScreen: false
}
При разработке Tom Select это снижает время пересборки при изменении компонентов UI и логики.
Чтобы Tom Select корректно удалял неиспользуемый код:
sideEffects: false{
"sideEffects": false
}
Это позволяет Rollup удалять неиспользуемые части селектора и плагинов.
export default {
input: 'src/index.ts',
external,
output: [
{ file: 'dist/index.esm.js', format: 'esm' },
{ file: 'dist/index.cjs.js', format: 'cjs' },
{ file: 'dist/index.umd.js', format: 'umd', name: 'TomSelect' }
],
plugins: [
resolve(),
commonjs(),
typescript(),
postcss({ extract: true }),
babel({ babelHelpers: 'bundled' }),
terser()
]
}