Олег Марков
Webpack и Vue полное практическое руководство
Введение
Webpack и Vue часто идут в паре, особенно в проектах, где нужен контролируемый процесс сборки, тонкая настройка производительности и гибкость. Да, у Vue есть собственные инструменты вроде Vue CLI и Vite, но Webpack по‑прежнему активно используется в реальных проектах, особенно в уже существующих кодовых базах и корпоративных приложениях.
Здесь вы увидите, как шаг за шагом настроить Webpack для Vue, понять, что именно делает сборщик, и как из базовой конфигурации прийти к удобному и предсказуемому окружению разработки.
Мы пройдем путь от минимального рабочего конфига до живой перезагрузки, работы с .vue‑файлами, загрузкой стилей, картинками, code splitting и оптимизацией для продакшена.
Базовые понятия Webpack в контексте Vue
Что делает Webpack в Vue‑проекте
Смотрите, коротко роли Webpack в вашем Vue‑приложении:
- собирает модули JavaScript в один или несколько бандлов;
- обрабатывает
.vue‑файлы (через vue-loader); - компилирует шаблоны и опцию template в render‑функции;
- подключает и преобразует стили (CSS, SCSS, PostCSS);
- обрабатывает ассеты (картинки, шрифты, SVG);
- разделяет код на чанки (code splitting) для более быстрой загрузки.
Vue сам по себе — это библиотека. Чтобы превратить проект с десятками файлов в один набор оптимизированных ресурсов для браузера, вам нужен сборщик, и в этом месте вступает Webpack.
Минимальный набор зависимостей
Если вы хотите собрать Vue‑приложение через Webpack вручную, обычно вам понадобятся:
- webpack и webpack-cli — сама сборка;
- webpack-dev-server или webpack-dev-server-подобный инструмент для разработки;
- vue и vue-loader — ядро фреймворка и загрузчик для
.vue; - @vue/compiler-sfc — компилятор однофайловых компонентов;
- babel-loader и набор пресетов/плагинов (если вы используете современный JS и хотите поддерживать старые браузеры);
- style-loader, css-loader и дополнительные лоадеры для стилей.
Давайте разберем это по шагам.
Инициализация проекта и установка зависимостей
Структура проекта
Для начала создадим простую структуру каталога:
- /project-root
- /src
- main.js
- App.vue
- package.json
- webpack.config.js
- /src
Такую структуру легко расширять, и она близка к тому, что вы увидите в большинстве Vue‑проектов.
Инициализация package.json
Откройте терминал в корне проекта и выполните:
npm init -y
# или
yarn init -y
Это создаст файл package.json с базовой конфигурацией.
Установка Vue и базового Webpack‑набора
Теперь поставим зависимости для минимальной сборки Vue через Webpack:
npm install vue
# Ставим сам Webpack и его CLI
npm install -D webpack webpack-cli
# Для разработки удобно иметь dev server
npm install -D webpack-dev-server
# Для работы с .vue файлами
npm install -D vue-loader @vue/compiler-sfc
# Плагин, который связывает vue-loader с Webpack
npm install -D vue-loader-plugin
Если вы работаете с Vue 3, вместо отдельного vue-loader-plugin вы будете использовать VueLoaderPlugin из пакета vue-loader. Чуть дальше вы увидите, как это выглядит в конфиге.
Первый Webpack-конфиг для Vue
Теперь вы увидите, как выглядит минимально рабочий webpack.config.js для Vue‑приложения.
Создайте файл webpack.config.js в корне проекта:
// Подключаем path для корректной работы с путями
const path = require('path')
// Импортируем плагин для vue-loader
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
// Указываем режим разработки
mode: 'development',
// Точка входа нашего приложения
entry: './src/main.js',
// Настройки вывода (куда Webpack положит собранный файл)
output: {
// Папка для выходных файлов
path: path.resolve(__dirname, 'dist'),
// Имя итогового файла бандла
filename: 'bundle.js'
},
module: {
rules: [
{
// Правило для обработки .vue файлов
test: /\.vue$/,
loader: 'vue-loader'
},
{
// Правило для обычных .js файлов
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
// Опции можно вынести в отдельный .babelrc
options: {
// Здесь мы указываем пресет для трансформации современного JS
presets: ['@babel/preset-env']
}
}
},
{
// Правило для CSS файлов
test: /\.css$/,
use: [
// Вставляет стили в DOM через <style> теги
'style-loader',
// Позволяет импортировать CSS в JS
'css-loader'
]
}
]
},
resolve: {
// Разрешаем импорт .vue файлов без явного указания расширения
extensions: ['.js', '.vue'],
alias: {
// Короткий путь '@' будет указывать на папку src
'@': path.resolve(__dirname, 'src')
}
},
plugins: [
// Этот плагин обязателен для работы vue-loader
new VueLoaderPlugin()
]
}
Важно: для babel-loader нам нужен сам Babel и пресет. Давайте их поставим:
npm install -D babel-loader @babel/core @babel/preset-env
Настройка входной точки и App.vue
main.js
Теперь давайте создадим минимальную точку входа для Vue‑приложения.
Файл src/main.js:
// Импортируем createApp (для Vue 3) или Vue (для Vue 2)
import { createApp } from 'vue'
// Импортируем корневой компонент приложения
import App from './App.vue'
// Создаем приложение и монтируем его в DOM
createApp(App).mount('#app')
Комментарии поясняют ключевые моменты — вы видите, откуда подключается корневой компонент и куда он монтируется.
App.vue
Теперь создадим простой однофайловый компонент.
Файл src/App.vue:
<template>
<!-- Шаблон нашего корневого компонента -->
<div class="app">
<h1>Webpack + Vue</h1>
<p>Это минимальный пример Vue-приложения, собранного с помощью Webpack</p>
</div>
</template>
<script>
// Здесь мы экспортируем объект компонента
export default {
name: 'App'
}
</script>
<style>
/* Простые стили для корневого блока */
.app {
font-family: sans-serif;
padding: 20px;
}
</style>
Как видите, здесь сразу используются три блока: template, script и style. Vue‑одиночный файл (Single File Component, SFC) — это и есть то, ради чего нужен vue-loader.
Подключение HTML и запуск dev server
HTML-шаблон
Webpack сам по себе не создает HTML‑файл по умолчанию. Есть два распространенных пути:
- Написать index.html вручную и подключить туда bundle.js.
- Использовать HtmlWebpackPlugin, который будет создавать HTML автоматически.
Давайте начнем с простого варианта — статического index.html.
Создайте dist/index.html с таким содержимым:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<title>Webpack с Vue</title>
</head>
<body>
<!-- Здесь будет смонтировано Vue-приложение -->
<div id="app"></div>
<!-- Подключаем собранный бандл Webpack -->
<script src="bundle.js"></script>
</body>
</html>
В продакшен-конфигурациях удобно использовать HtmlWebpackPlugin, но пока вы можете начать и с такого варианта.
Скрипты в package.json
Добавим команду сборки и запуска dev server в package.json.
Фрагмент package.json:
{
"scripts": {
"build": "webpack",
"dev": "webpack serve --open --hot"
}
}
Здесь:
- build запустит Webpack в режиме по умолчанию (который мы указали в конфиге);
- dev поднимет webpack-dev-server с горячей перезагрузкой.
Настройка webpack-dev-server
Чтобы команды dev работали, добавим соответствующую часть в webpack.config.js:
module.exports = {
// ...остальные настройки остаются
devServer: {
// Папка, из которой dev-server будет раздавать статические файлы
static: {
directory: path.join(__dirname, 'dist')
},
// Включаем поддержку history API для SPA
historyApiFallback: true,
// Порт, на котором будет работать dev-server
port: 8080,
// Включаем hot module replacement
hot: true,
// Автоматически открывать браузер при старте
open: true
}
}
Теперь вы можете запустить:
npm run dev
И увидеть ваше Vue‑приложение в браузере.
Работа с .vue‑компонентами и структура проекта
Организация компонентов
Обычно удобно разбивать приложение на папки:
- /src
- /components
- HelloWorld.vue
- Header.vue
- App.vue
- main.js
- /components
Создадим пример компонента HelloWorld.vue:
<template>
<!-- Компонент показывает текст и счетчик -->
<div class="hello">
<h2>{{ msg }}</h2>
<p>Счетчик - {{ count }}</p>
<button @click="increment">Увеличить</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
// Принимаем пропс msg от родителя
props: {
msg: {
type: String,
required: true
}
},
data() {
return {
// Локальное состояние компонента
count: 0
}
},
methods: {
// Метод увеличивает значение счетчика
increment() {
this.count++
}
}
}
</script>
<style scoped>
/* scoped означает, что стили применяются только к этому компоненту */
.hello {
border: 1px solid #ccc;
padding: 10px;
}
</style>
Теперь подключим этот компонент в App.vue:
<template>
<div class="app">
<h1>Webpack + Vue</h1>
<!-- Используем дочерний компонент и передаем ему пропс -->
<HelloWorld msg="Компонент HelloWorld работает" />
</div>
</template>
<script>
// Импортируем дочерний компонент
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
// Регистрируем компонент локально
HelloWorld
}
}
</script>
<style>
.app {
font-family: sans-serif;
padding: 20px;
}
</style>
Здесь вы видите типичный поток: App.vue — корневой компонент, который подключает дочерние компоненты. Webpack через vue-loader превращает все это в обычный JS, понятный браузеру.
Работа со стилями: CSS, SCSS, PostCSS
Базовая обработка CSS
Мы уже добавили правило для CSS в webpack.config.js. Оно использует:
- css-loader — чтобы
import './style.css'в JS работал; - style-loader — чтобы полученный CSS добавлялся в DOM.
Теперь вы можете, например, импортировать глобальные стили в main.js:
// Импортируем корневой CSS-файл
import './styles/global.css'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
global.css:
/* Глобальные стили для всего приложения */
body {
margin: 0;
background-color: #f5f5f5;
}
Webpack соберет этот CSS в бандл, а style-loader вставит его в DOM.
Поддержка SCSS (Sass)
Если вы хотите использовать Sass/SCSS в .vue‑файлах или отдельных стилевых файлах, добавьте зависимости:
npm install -D sass sass-loader
И обновите правило для стилей в webpack.config.js:
module.exports = {
// ...
module: {
rules: [
// ...правило для .vue и .js
{
test: /\.scss$/,
use: [
// Вставляет CSS в DOM
'style-loader',
// Обрабатывает @import и url()
'css-loader',
// Компилирует SCSS в CSS
'sass-loader'
]
}
]
}
}
Теперь давайте посмотрим на пример использования SCSS в компоненте:
<style lang="scss" scoped>
$app-color: #42b983;
/* Используем переменную Sass */
.app {
color: $app-color;
}
</style>
Здесь lang="scss" говорит vue-loader использовать цепочку лоадеров для SCSS.
Вынесение CSS в отдельные файлы (для продакшена)
Для продакшена часто нужно собирать стили в отдельный CSS‑файл, а не вставлять их в DOM через style‑теги. Для этого используется mini-css-extract-plugin.
Установите:
npm install -D mini-css-extract-plugin
И модифицируйте конфиг (как пример — только для продакшен‑режима):
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: [
// В продакшене лучше использовать MiniCssExtractPlugin.loader
process.env.NODE_ENV === 'production'
? MiniCssExtractPlugin.loader
: 'style-loader',
'css-loader'
]
}
]
},
plugins: [
new VueLoaderPlugin(),
// Плагин для вынесения CSS в отдельные файлы
new MiniCssExtractPlugin({
// Имя выходного CSS файла
filename: '[name].[contenthash].css'
})
]
}
Такая конфигурация позволяет в режиме разработки держать стили в памяти через style-loader, а в продакшене собирать отдельный CSS‑файл.
Обработка ассетов: картинки, шрифты, SVG
Использование asset modules (Webpack 5)
В Webpack 5 появился встроенный механизм asset modules, который заменяет file-loader и url-loader для многих задач.
Пример правила для ассетов:
module.exports = {
// ...
module: {
rules: [
// ...другие правила
{
// Обрабатываем картинки любых распространенных форматов
test: /\.(png|jpe?g|gif|svg)$/i,
type: 'asset',
parser: {
// Файлы меньше 8kb будут инлайниться в base64
dataUrlCondition: {
maxSize: 8 * 1024
}
}
},
{
// Обрабатываем шрифты
test: /\.(woff2?|eot|ttf|otf)$/i,
type: 'asset/resource'
}
]
}
}
Теперь вы можете импортировать картинки прямо в компонентах:
<template>
<div class="logo-wrapper">
<!-- Используем импортированную картинку как src -->
<img :src="logoUrl" alt="Логотип" />
</div>
</template>
<script>
// Импортируем картинку, чтобы Webpack положил ее в выходную папку
import logo from '../assets/logo.png'
export default {
name: 'Logo',
data() {
return {
// Сохраняем путь к картинке в состоянии
logoUrl: logo
}
}
}
</script>
Webpack подставит корректный путь к файлу в dist, а не исходный ../assets/logo.png.
Настройка окружений: development и production
Разделение конфигов
В реальных проектах обычно есть отдельные конфиги:
- webpack.common.js — общий;
- webpack.dev.js — для разработки;
- webpack.prod.js — для продакшена.
Давайте схематично разберем общий подход.
Файл webpack.common.js:
const path = require('path')
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: './src/main.js',
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader'
},
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
// Здесь могут быть правила для ассетов
]
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
'@': path.resolve(__dirname, 'src')
}
},
plugins: [new VueLoaderPlugin()]
}
Файл webpack.dev.js:
const { merge } = require('webpack-merge')
const path = require('path')
const common = require('./webpack.common.js')
module.exports = merge(common, {
// Указываем режим разработки
mode: 'development',
// Исходные карты кода для удобной отладки
devtool: 'eval-source-map',
output: {
// Папка для dev-сборки
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
devServer: {
static: {
directory: path.join(__dirname, 'dist')
},
historyApiFallback: true,
port: 8080,
hot: true,
open: true
}
})
Файл webpack.prod.js:
const { merge } = require('webpack-merge')
const path = require('path')
const common = require('./webpack.common.js')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = merge(common, {
// Режим продакшена включает оптимизации по умолчанию
mode: 'production',
devtool: 'source-map',
output: {
// Путь к папке для продакшн-сборки
path: path.resolve(__dirname, 'dist'),
// Используем хэши для кэширования
filename: '[name].[contenthash].js',
clean: true // Очищает папку dist перед сборкой
},
module: {
rules: [
{
test: /\.css$/,
use: [
// В продакшене вытаскиваем CSS в отдельный файл
MiniCssExtractPlugin.loader,
'css-loader'
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
// Имя CSS файла с хэшем
filename: '[name].[contenthash].css'
})
]
})
Теперь в package.json можно добавить:
{
"scripts": {
"dev": "webpack serve --config webpack.dev.js",
"build": "webpack --config webpack.prod.js"
}
}
Такой подход помогает отдельно управлять настройками разработки и продакшена, не смешивая все в одном большом файле.
Code splitting и динамический импорт во Vue
Зачем нужен code splitting
Если ваше приложение растет, один большой бандл может стать тяжелым. Code splitting позволяет разбивать код на части:
- уменьшить время первой загрузки;
- подгружать реже используемый код по требованию (lazy loading).
Webpack поддерживает динамический импорт, который особенно удобен в связке с Vue Router.
Пример динамического импорта компонента
Давайте посмотрим на простой пример вне роутера:
<template>
<div>
<button @click="load">Загрузить компонент</button>
<!-- Рендерим компонент только когда он загружен -->
<component v-if="AsyncComponent" :is="AsyncComponent" />
</div>
</template>
<script>
export default {
name: 'AsyncExample',
data() {
return {
// Здесь мы будем хранить загруженный компонент
AsyncComponent: null
}
},
methods: {
async load() {
// Динамически импортируем компонент
const module = await import('./HeavyComponent.vue')
// Сохраняем компонент из модуля в состояние
this.AsyncComponent = module.default
}
}
}
</script>
Webpack создаст отдельный чанк для HeavyComponent.vue, который будет загружаться только при вызове метода load.
Lazy loading роутов (с Vue Router)
Этот подход особенно полезен с Vue Router, когда вы хотите грузить страницы по требованию.
Конфигурация роутера (например, src/router/index.js):
import { createRouter, createWebHistory } from 'vue-router'
// Создаем ленивый импорт компонента страницы
const About = () => import('../views/About.vue')
// Можно дать подсказку Webpack по имени чанка
const Home = () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
const routes = [
{
path: '/',
name: 'Home',
component: Home // Компонент Home загрузится только при переходе на этот путь
},
{
path: '/about',
name: 'About',
component: About // Аналогично, About загрузится лениво
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
Webpack сгенерирует отдельные чанки для Home и About, что улучшит скорость начальной загрузки.
Оптимизация: tree shaking, кэширование, splitChunks
Tree shaking в Vue‑проектах
Tree shaking — это удаление неиспользуемого кода из сборки. В контексте Vue:
- используйте модульный импорт (например, отдельных функций из библиотек);
- не импортируйте целиком большие пакеты, если нужен только кусок.
Пример:
// Плохая практика - импортируем всю библиотеку
import _ from 'lodash'
// Лучшая практика - импортируем только нужную функцию
import debounce from 'lodash/debounce'
Webpack в режиме production по умолчанию включает tree shaking при условии, что код использует ES‑модули.
Настройка splitChunks
Для более гибкого разделения кода можно использовать splitChunks.
Фрагмент webpack.prod.js:
module.exports = {
// ...
optimization: {
splitChunks: {
// Указываем, что разделять нужно и асинхронные, и синхронные импорты
chunks: 'all',
// Минимальный размер чанка
minSize: 20000,
cacheGroups: {
// Группа для сторонних библиотек
vendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
// Более высокий приоритет для этой группы
priority: -10
},
// Группа для общих модулей приложения
common: {
minChunks: 2,
name: 'common',
priority: -20,
reuseExistingChunk: true
}
}
},
// Включаем отдельный чанк для runtime-кода Webpack
runtimeChunk: 'single'
}
}
Так вы получите, например, отдельный vendors.
Подключение HtmlWebpackPlugin и шаблонизация HTML
Ранее мы создавали index.html вручную. Для продакшн‑сборок и более сложных проектов удобно, когда HTML генерируется автоматически.
Установите плагин:
npm install -D html-webpack-plugin
И добавьте его в webpack.common.js (или основной конфиг):
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin(),
new HtmlWebpackPlugin({
// Заголовок страницы
title: 'Vue + Webpack',
// Шаблон для генерации HTML
template: './public/index.html'
})
]
}
А теперь создадим шаблон HTML в public/index.html:
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<!-- Заголовок можно переопределять из HtmlWebpackPlugin -->
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!-- Элемент, куда будет монтироваться Vue -->
<div id="app"></div>
</body>
</html>
Плагин автоматически добавит теги script и link с вашими бандлами в итоговый HTML.
Отладка: source map и удобство разработки
Source maps для Vue и Webpack
Source map нужны, чтобы в инструментах разработчика видеть исходный код (SFC, исходный JS), а не уже собранный бандл.
- В dev‑конфиге можно использовать быстрые карты, например eval-source-map.
- В prod — полноценные source-map, но с учетом безопасности.
Пример (мы уже частично делали это):
// webpack.dev.js
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map'
})
// webpack.prod.js
module.exports = merge(common, {
mode: 'production',
devtool: 'source-map'
})
Vue‑шаблоны и .vue‑файлы тоже будут отображаться корректно в девтулзах, если vue-loader и source-map настроены.
Интеграция с линтерами и типизацией (ESLint, TypeScript)
Подключение ESLint
Чтобы держать код в порядке, удобно использовать ESLint с соответствующим лоадером.
Установка:
npm install -D eslint eslint-webpack-plugin
Добавление плагина в конфиг:
const ESLintPlugin = require('eslint-webpack-plugin')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin(),
// Плагин ESLint будет анализировать файлы на лету
new ESLintPlugin({
// Каталоги, в которых искать файлы
context: 'src',
// Расширения файлов для проверки
extensions: ['js', 'vue']
})
]
}
ESLint можно дополнительно настроить через .eslintrc, чтобы учитывать особенности Vue (через eslint-plugin-vue).
Поддержка TypeScript (кратко)
Если вы хотите использовать TypeScript с Vue и Webpack, обычно потребуется:
- ts-loader или babel-loader с @babel/preset-typescript;
- настройка resolve.extensions;
- конфигурация Vue для работы с
<script lang="ts">.
Набросок минимальной настройки:
npm install -D typescript ts-loader
В webpack.config.js:
module.exports = {
// ...
module: {
rules: [
// ...vue, css и другие правила
{
// Обрабатываем .ts файлы
test: /\.ts$/,
loader: 'ts-loader',
options: {
// Включаем поддержку .vue файлов
appendTsSuffixTo: [/\.vue$/]
},
exclude: /node_modules/
}
]
},
resolve: {
// Добавляем .ts в список расширений
extensions: ['.ts', '.js', '.vue']
}
}
Теперь в компонентах вы можете писать:
<script lang="ts">
// Здесь мы пишем код компонента на TypeScript
export default {
// Опции компонента остаются теми же
name: 'TsComponent'
}
</script>
TypeScript в связке с Webpack и Vue — обширная тема, но вы уже видите, как связующий элемент (Webpack) помогает все это собрать в целое.
Заключение
Вы прошли через ключевые элементы настройки Webpack для Vue‑приложения: от минимальной конфигурации до разбиения кода на чанки, вынесения стилей, генерации HTML и поддержки разных окружений.
Важно понимать общую картину: Webpack — это конструктор, а Vue — одна из технологий, которые он умеет собирать. Правильно настроенный конфиг облегчает разработку, повышает скорость загрузки приложения и делает процесс сборки предсказуемым.
Дальше полезно развивать конфигурацию вглубь под задачи конкретного проекта: подключать дополнительные оптимизации, настраивать кэширование, внедрять аналитику размера бандлов и интеграцию с CI/CD. Но основа остается той же — входные точки, правила (loaders), плагины, режимы окружения и структура проекта.
Частозадаваемые технические вопросы
Как настроить алиасы, чтобы импортировать из @components вместо относительных путей?
Добавьте в resolve.alias нужный путь:
// В webpack.config.js
const path = require('path')
module.exports = {
// ...
resolve: {
extensions: ['.js', '.vue'],
alias: {
'@': path.resolve(__dirname, 'src'),
// Здесь создаем алиас для папки components
'@components': path.resolve(__dirname, 'src/components')
}
}
}
Теперь можно писать:
import MyComp from '@components/MyComp.vue'
// вместо
// import MyComp from '../../components/MyComp.vue'
Как настроить HMR (горячую перезагрузку) для Vue с Webpack 5?
Webpack 5 и vue-loader уже поддерживают HMR. Проверьте:
- В devServer включен hot: true.
- Входной файл использует createApp без ручной перерисовки.
- В плагинах подключен VueLoaderPlugin.
Если HMR не работает, удалите кастомный код с module.hot.accept в main.js — Vue сам обрабатывает обновления компонентов через vue-loader.
Как подключить environment‑переменные (например, API_URL) в сборку Webpack?
Используйте DefinePlugin:
const webpack = require('webpack')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin(),
// Передаем переменные окружения в код
new webpack.DefinePlugin({
// Здесь мы сериализуем значение в строку
__API_URL__: JSON.stringify(process.env.API_URL || 'https://api.local')
})
]
}
В коде:
// Используем глобальную константу, заданную через Webpack
console.log('API URL -', __API_URL__)
Как добавить поддержку PWA (service worker, manifest) в Vue‑проект на Webpack?
- Установите workbox-webpack-plugin.
- Подключите GenerateSW или InjectManifest в продакшн‑конфиг.
Пример с GenerateSW:
npm install -D workbox-webpack-plugin
// В webpack.prod.js
const { GenerateSW } = require('workbox-webpack-plugin')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin(),
new GenerateSW({
// Кешируем все файлы по умолчанию
clientsClaim: true,
skipWaiting: true
})
]
}
Создайте manifest.json в public и подключите его через HtmlWebpackPlugin (через template или тег link). После продакшн‑сборки приложение будет работать как PWA.
Как уменьшить размер бандла, если в проекте используется moment.js или другая тяжелая библиотека?
- Замените тяжелую библиотеку на легкий аналог (date-fns вместо moment.js).
- Если замена невозможна, используйте плагин IgnorePlugin, чтобы исключить локали:
const webpack = require('webpack')
module.exports = {
// ...
plugins: [
new VueLoaderPlugin(),
// Игнорируем локали moment.js
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/
})
]
}
- Включите анализатор бандла (webpack-bundle-analyzer), чтобы увидеть самые тяжелые зависимости и при необходимости разделить их на отдельные чанки через splitChunks.
Постройте личный план изучения Vue до уровня Middle — бесплатно!
Vue — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Vue
Лучшие курсы по теме

Vue 3 и Pinia
Антон Ларичев
TypeScript с нуля
Антон Ларичев