Интеграция Tom Sel ect в сборку на Webpack требует корректной настройки обработки JavaScript-модулей, CSS-стилей и потенциальных зависимостей, связанных с кастомизацией UI. Библиотека распространяется как ESM/CommonJS модуль и предполагает наличие соответствующей конфигурации сборщика для стабильной работы в dev и production окружениях.
Основная сложность при подключении заключается в необходимости корректно обработать стили Tom Select и обеспечить совместимость с системой модулей проекта.
Базовый набор пакетов включает саму библиотеку и инструменты сборки стилей:
npm install tom-select
npm install --save-dev webpack webpack-cli webpack-dev-server
При использовании SCSS добавляются дополнительные зависимости:
npm install --save-dev sass sass-loader css-loader style-loader mini-css-extract-plugin
Типовая конфигурация Webpack для проекта с Tom Select включает обработку JavaScript и CSS:
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
clean: true
},
mode: 'development',
devtool: 'source-map',
module: {
rules: []
}
};
Импорт библиотеки выполняется напрямую из node_modules:
import TomSelect fr om 'tom-select';
import 'tom-select/dist/css/tom-select.css';
Инициализация:
const sel ect = new TomSelect('#select', {
create: true,
sortField: 'text'
});
Tom Select требует подключения встроенных стилей. Для этого используется правило обработки CSS:
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
При использовании production-сборки предпочтительно извлекать стили в отдельные файлы:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'styles.css'
})
]
};
Разделение конфигурации позволяет оптимизировать сборку и упростить поддержку проекта.
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
module.exports = {
mode: 'development',
devtool: 'eval-source-map',
devServer: {
static: './dist',
hot: true,
port: 3000
}
};
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map',
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'styles.[contenthash].css'
})
],
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
При расширенной стилизации используется SCSS, что позволяет переопределять переменные и расширять базовые стили.
module.exports = {
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'sass-loader'
]
}
]
}
};
Импорт SCSS:
import './styles/app.scss';
import 'tom-select/dist/css/tom-select.css';
При масштабировании проекта целесообразно настроить алиасы:
module.exports = {
resolve: {
alias: {
'@components': path.resolve(__dirname, 'src/components'),
'@styles': path.resolve(__dirname, 'src/styles')
}
}
};
Это упрощает подключение кастомных обёрток над Tom Select:
import createSelect fr om '@components/sel ect';
Tom Select поддерживает ES-модули, однако в некоторых сборках требуется учитывать CommonJS-экспорт.
Настройка для корректного резолва:
module.exports = {
resolve: {
extensions: ['.js', '.json'],
mainFields: ['module', 'main']
}
};
Для уменьшения размера финального бандла используются следующие техники:
module.exports = {
mode: 'production',
optimization: {
usedExports: true
}
};
module.exports = {
optimization: {
splitChunks: {
chunks: 'all'
}
}
};
Tom Select может быть выделен в отдельный chunk:
import('tom-select').then(({ default: TomSelect }) => {
new TomSelect('#select');
});
Если проект использует кастомные иконки или изображения в шаблонах Tom Select:
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|svg|gif)$/,
type: 'asset/resource'
}
]
}
};
module.exports = {
devServer: {
static: {
directory: path.join(__dirname, 'dist')
},
compress: true,
hot: true,
open: true
}
};
Tom Select корректно работает с hot reload при условии сохранения состояния DOM-элемента и повторной инициализации после обновления модуля.
При использовании hot module replacement требуется контролировать пересоздание инстансов:
let select;
function init() {
if (select) {
select.destroy();
}
select = new TomSelect('#select', {
create: true
});
}
init();
if (module.hot) {
module.hot.accept(() => {
init();
});
}
При использовании TypeScript добавляется ts-loader:
npm install --save-dev typescript ts-loader
Конфигурация:
module.exports = {
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts', '.js']
}
};
Использование Tom Select с типизацией:
import TomSelect fr om 'tom-select';
const select = new TomSelect('#select', {
create: true
});
При масштабной архитектуре стили Tom Select часто переопределяются через глобальные SCSS-файлы:
.tom-select {
border-radius: 6px;
.ts-control {
min-height: 40px;
}
.ts-dropdown {
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.12);
}
}
Такая схема требует строгого порядка загрузки CSS в Webpack, где базовые стили подключаются до кастомных.
Для production-сборок применяется хеширование файлов:
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist'),
clean: true
}
Это предотвращает проблемы с устаревшими стилями Tom Select в браузерном кеше и обеспечивает корректное обновление UI-компонента после деплоя.