Библиотека Vivus распространяется как npm-пакет и интегрируется в
модульную систему JavaScript без дополнительных обёрток. В контексте
Webpack она рассматривается как обычная зависимость, попадающая в
итоговый бандл через механизм import.
npm install vivus
После установки пакет становится доступен для импорта в коде приложения:
import Vivus from 'vivus';
В современных конфигурациях Webpack дополнительная настройка для самой библиотеки обычно не требуется, поскольку она не зависит от DOM-специфичных трансформаций на этапе сборки.
Ключевой аспект работы Vivus связан с тем, как SVG попадает в
приложение. Анимация строится на поэтапной отрисовке путей
(<path>), поэтому доступ к структуре SVG необходим
либо как к DOM-элементу, либо как к строковому содержимому.
В Webpack применяются несколько стратегий обработки SVG.
Современный подход основан на встроенных asset modules:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
type: 'asset/source'
}
]
}
};
Такой режим возвращает содержимое SVG как строку, что упрощает дальнейшую вставку в DOM.
Пример импорта:
import logo from './logo.svg';
logo содержит исходный XML SVG.
В более старых конфигурациях применялся raw-loader:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: 'raw-loader'
}
]
}
};
Результат аналогичен asset/source — SVG становится строкой.
Альтернативный вариант — обработка SVG как файла:
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
type: 'asset/resource'
}
]
}
};
В этом случае возвращается URL на файл, что ограничивает применение Vivus, так как библиотеке требуется доступ к DOM-структуре SVG, а не к внешнему ресурсу.
Базовая конфигурация включает обработку JavaScript, SVG и HTML-контейнер.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
clean: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.svg$/,
type: 'asset/source'
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
mode: 'development'
};
Работа Vivus основана на передаче DOM-элемента или идентификатора
SVG-контейнера. При использовании SVG как строки применяется вставка в
DOM через innerHTML.
import Vivus from 'vivus';
import logo from './logo.svg';
const container = document.getElementById('svg-container');
container.innerHTML = logo;
new Vivus('svg-container', {
type: 'delayed',
duration: 200,
animTimingFunction: Vivus.EASE
});
SVG должен содержать идентификатор контейнера или быть обёрнут в
элемент с заданным id, так как Vivus ищет DOM-ноду по
селектору.
При работе с несколькими анимациями применяется модульная структура импорта:
import icon1 from './icons/icon1.svg';
import icon2 from './icons/icon2.svg';
document.querySelector('#icon1').innerHTML = icon1;
document.querySelector('#icon2').innerHTML = icon2;
new Vivus('icon1', { duration: 120 });
new Vivus('icon2', { duration: 180 });
Каждый экземпляр Vivus привязывается к отдельному DOM-узлу, внутри
которого присутствуют <path> элементы.
Минификация SVG через svgo-loader или встроенные
оптимизаторы Webpack влияет на структуру путей. Vivus опирается на
наличие stroke-ориентированных элементов.
Типичная настройка:
{
test: /\.svg$/,
use: [
{
loader: 'svgo-loader',
options: {
plugins: [
{ name: 'removeViewBox', active: false }
]
}
}
]
}
Удаление viewBox и объединение путей приводит к
нарушению анимации, поскольку теряется структура отдельных
сегментов.
Vivus не требует специфических трансформаций, но Webpack-проекты часто включают Babel для остального кода.
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
Совместимость обеспечивается транспиляцией синтаксиса, используемого в обвязке анимаций и логике инициализации.
Webpack поддерживает ленивую загрузку SVG, что влияет на момент инициализации Vivus.
import('./icons/animated.svg').then((module) => {
const svg = module.default;
const container = document.getElementById('lazy-svg');
container.innerHTML = svg;
new Vivus('lazy-svg', { duration: 150 });
});
Такой подход переносит загрузку графики в отдельный chunk, уменьшая размер основного бандла.
При использовании SplitChunksPlugin SVG-ресурсы могут
попадать в отдельные чанки:
optimization: {
splitChunks: {
chunks: 'all'
}
}
Vivus инициализируется только после полной загрузки DOM-структуры SVG, поэтому порядок загрузки модулей влияет на корректность запуска анимации.
Webpack обрабатывает стили SVG через css-loader и
style-loader, если SVG содержит встроенные стили.
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
Анимация Vivus ориентирована на stroke-dasharray и
stroke-dashoffset, поэтому любые внешние CSS-правила,
изменяющие эти свойства, напрямую влияют на поведение анимации.
SVG, оптимизированный под спрайты или объединённый через
symbol и use, теряет прямой доступ к путям,
что делает его несовместимым с классическим режимом Vivus.
Структура:
<svg>
<symbol id="icon">
<path ... />
</symbol>
</svg>
В таком формате требуется предварительная инстанциация символа в DOM перед запуском анимации.
В production-режиме Webpack активирует минификацию и tree-shaking:
mode: 'production'
Vivus попадает в бандл как ESM/CJS-зависимость, а SVG остаются либо встроенными строками, либо отдельными ресурсами в зависимости от типа loader’а.
Снижение размера достигается за счёт:
Архитектурно связка Webpack + Vivus + SVG строится вокруг трёх уровней:
path-элементамиТакая композиция делает поведение предсказуемым при условии сохранения исходной структуры SVG без агрессивной оптимизации.