Webpack и Vue полное практическое руководство

19 февраля 2026
Автор

Олег Марков

Введение

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

Такую структуру легко расширять, и она близка к тому, что вы увидите в большинстве 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‑файл по умолчанию. Есть два распространенных пути:

  1. Написать index.html вручную и подключить туда bundle.js.
  2. Использовать 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

Создадим пример компонента 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..js с зависимостями из node_modules и сможете лучше использовать кэш браузера.


Подключение 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. Проверьте:

  1. В devServer включен hot: true.
  2. Входной файл использует createApp без ручной перерисовки.
  3. В плагинах подключен 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?

  1. Установите workbox-webpack-plugin.
  2. Подключите 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 или другая тяжелая библиотека?

  1. Замените тяжелую библиотеку на легкий аналог (date-fns вместо moment.js).
  2. Если замена невозможна, используйте плагин IgnorePlugin, чтобы исключить локали:
const webpack = require('webpack')

module.exports = {
  // ...
  plugins: [
    new VueLoaderPlugin(),
    // Игнорируем локали moment.js
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/
    })
  ]
}
  1. Включите анализатор бандла (webpack-bundle-analyzer), чтобы увидеть самые тяжелые зависимости и при необходимости разделить их на отдельные чанки через splitChunks.
Тестирование с Vitest - практическое руководство для разработчиковСтрелочка вправо

Постройте личный план изучения Vue до уровня Middle — бесплатно!

Vue — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Vuex - полное руководство по управлению состоянием во Vue приложенияхРеактивные объекты reactive-objects - подробное руководство с примерамиРеактивные ссылки ref - полный разбор для разработчиковРеактивные переменные - концепция reactive и практические примерыМеханизм Provide Inject - как он работает и когда применятьPinia современный менеджер состояния для VueЛокальное состояние local state в веб разработкеГлобальное состояние в приложениях - global state
Работа с обновлениями компонента и жизненным циклом updateОбзор и использование утилит Vue для удобной разработкиРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание и применение Composition API в Vue 3Понимание core функционала Vue и его применениеПонимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
Функция append в Go GolangОтображение компонента mounted - практическое руководствоХуки жизненного цикла компонентов - полное руководство для разработчиковУничтожение компонента destroyed - как правильно очищать ресурсы и подпискиИнициализация данных в состоянии created - как и когда подготавливать данные в приложенииОбновление компонента beforeUpdate во VueМонтирование компонента - хук beforeMount в VueРазрушение компонента во Vue - beforeDestroy и beforeUnmountСоздание экземпляра beforeCreate - полный разбор жизненного цикла
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Слоты компонента - концепция и практическое использованиеРегистрация компонентов component-registration в приложениях с внедрением зависимостейProps компонента в React - полный разбор с примерамиФункциональные компоненты в React - функциональный подход к построению интерфейсовСобытия компонента - events в современных интерфейсахСоздание компонента component - практическое руководствоДинамические компоненты - dynamic-componentsАсинхронные компоненты async-components - практическое руководство
Наблюдатели watchers - от паттерна до практических реализацийУправление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsШаблоны Vue templates - практическое руководство для разработчиковИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиРеактивность Vue reactivity - как это работает под капотом и как этим пользоватьсяПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueОпции компонента в Go - паттерн component-optionsРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueИспользование хуков жизненного цикла в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreВычисляемые свойства computed во Vue.jsСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueОсновы Vue - vue-basics для уверенного стартаИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueТелепортация - архитектура и реализация в серверных приложенияхРабота с teleport для управления DOM во VueSuspense в React - управление асинхронными данными и ленивой загрузкойПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиПлагины Vue vue-plugins - полное практическое руководствоРуководство по nextTick для работы с DOMМиксины - mixins в современном программированииJSX в Vue с использованием плагина vue-jsxСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьКастомные элементы - Custom Elements в современном JavaScriptИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Vue 3 и Pinia

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.9
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий