Настройка бандлера Vite для веб-проекта

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Настройка бандлера Vite для веб-проекта
Простая
от 4 часов до 2 рабочих дней
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Настройка бандлера Vite для веб-проекта

Vite использует нативные ES-модули браузера в dev-режиме — файлы отдаются напрямую, без сборки. HMR работает точечно: изменился один файл — обновился один модуль. Для production сборки использует Rollup.

Результат: холодный старт dev-сервера за 300–500 мс вместо 30–60 секунд у Webpack для крупных проектов.

Что входит в работу

Настройка vite.config.ts для React/Vue/Svelte, TypeScript, CSS/PostCSS, алиасы путей, proxy на backend API, code splitting, переменные окружения, production-оптимизации.

Установка

# React + TypeScript
npm create vite@latest my-app -- --template react-ts
cd my-app && npm install

# или Vue
npm create vite@latest my-app -- --template vue-ts

# или Svelte
npm create vite@latest my-app -- --template svelte-ts

vite.config.ts — React-проект

import { defineConfig, loadEnv } from 'vite'
import react from '@vitejs/plugin-react-swc'
import path from 'path'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '')

  return {
    plugins: [
      react(),
    ],

    resolve: {
      alias: {
        '@': path.resolve(__dirname, './src'),
        '@components': path.resolve(__dirname, './src/components'),
        '@hooks': path.resolve(__dirname, './src/hooks'),
        '@utils': path.resolve(__dirname, './src/utils'),
        '@assets': path.resolve(__dirname, './src/assets'),
      },
    },

    server: {
      port: 3000,
      strictPort: true, // ошибка если порт занят, а не выбор другого
      proxy: {
        '/api': {
          target: env.VITE_API_URL ?? 'http://localhost:8000',
          changeOrigin: true,
          rewrite: (p) => p.replace(/^\/api/, ''),
        },
        '/ws': {
          target: env.VITE_WS_URL ?? 'ws://localhost:8000',
          ws: true,
        },
      },
      hmr: {
        overlay: true,
      },
    },

    preview: {
      port: 4000,
      strictPort: true,
    },

    css: {
      modules: {
        localsConvention: 'camelCaseOnly',
      },
      preprocessorOptions: {
        scss: {
          additionalData: `@import "@/styles/variables.scss";`,
        },
      },
    },

    build: {
      target: 'es2020',
      outDir: 'dist',
      sourcemap: mode !== 'production',
      minify: 'esbuild',
      rollupOptions: {
        output: {
          manualChunks: {
            'vendor-react': ['react', 'react-dom'],
            'vendor-router': ['react-router-dom'],
            'vendor-query': ['@tanstack/react-query'],
            'vendor-ui': ['@radix-ui/react-dialog', '@radix-ui/react-dropdown-menu'],
          },
          chunkFileNames: 'assets/js/[name]-[hash].js',
          entryFileNames: 'assets/js/[name]-[hash].js',
          assetFileNames: 'assets/[ext]/[name]-[hash].[ext]',
        },
      },
      // не выводить предупреждения о размере чанков в CI
      chunkSizeWarningLimit: 600,
    },

    optimizeDeps: {
      include: [
        'react',
        'react-dom',
        'react-router-dom',
        '@tanstack/react-query',
      ],
    },

    define: {
      __APP_VERSION__: JSON.stringify(process.env.npm_package_version),
    },
  }
})

tsconfig.json — алиасы

Алиасы нужно описать и в vite.config.ts, и в tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "bundler",
    "jsx": "react-jsx",
    "strict": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@hooks/*": ["src/hooks/*"],
      "@utils/*": ["src/utils/*"]
    },
    "types": ["vite/client"]
  }
}

Переменные окружения

# .env.development
VITE_API_URL=http://localhost:8000
VITE_APP_NAME=MyApp Dev

# .env.production
VITE_API_URL=https://api.example.com
VITE_APP_NAME=MyApp

Только переменные с префиксом VITE_ попадают в браузерный код:

// автотипизация
/// <reference types="vite/client" />

interface ImportMetaEnv {
  readonly VITE_API_URL: string
  readonly VITE_APP_NAME: string
}

interface ImportMeta {
  readonly env: ImportMetaEnv
}

// использование
const apiUrl = import.meta.env.VITE_API_URL

Плагины под разные задачи

npm install -D vite-plugin-svgr              # SVG → React-компоненты
npm install -D @vitejs/plugin-legacy          # поддержка старых браузеров
npm install -D vite-plugin-pwa               # Progressive Web App
npm install -D rollup-plugin-visualizer      # анализ бандла
npm install -D vite-plugin-checker           # TypeScript + ESLint в dev
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'
import svgr from 'vite-plugin-svgr'
import legacy from '@vitejs/plugin-legacy'
import { VitePWA } from 'vite-plugin-pwa'
import { visualizer } from 'rollup-plugin-visualizer'
import checker from 'vite-plugin-checker'

export default defineConfig({
  plugins: [
    react(),

    svgr({
      svgrOptions: { exportType: 'named', ref: true },
    }),

    checker({
      typescript: true,
      eslint: { lintCommand: 'eslint src --ext .ts,.tsx' },
    }),

    VitePWA({
      registerType: 'autoUpdate',
      manifest: {
        name: 'My App',
        short_name: 'App',
        theme_color: '#1a1a2e',
        icons: [
          { src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
          { src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
        ],
      },
    }),

    process.env.ANALYZE && visualizer({
      open: true,
      gzipSize: true,
      brotliSize: true,
      filename: 'dist/bundle-stats.html',
    }),
  ].filter(Boolean),
})

Code splitting через lazy

// src/router.tsx
import { lazy, Suspense } from 'react'
import { createBrowserRouter } from 'react-router-dom'

const ProductsPage = lazy(() =>
  import('./pages/ProductsPage')
  // подсказка Rollup по имени чанка
  // import(/* rollupOptions: { name: "products" } */ './pages/ProductsPage')
)

export const router = createBrowserRouter([
  {
    path: '/',
    element: <Layout />,
    children: [
      {
        path: 'products',
        element: (
          <Suspense fallback={<PageSkeleton />}>
            <ProductsPage />
          </Suspense>
        ),
      },
    ],
  },
])

Статика и ассеты

// импорт с типизацией
import logoUrl from '@assets/logo.svg?url'         // строка URL
import LogoComponent from '@assets/logo.svg?react'  // React-компонент (svgr)
import rawSvg from '@assets/icon.svg?raw'           // сырой SVG как строка

// URL для web worker
import MyWorker from './workers/heavy.worker?worker'
const worker = new MyWorker()

Многоцелевая сборка (lib mode)

Если проект — UI-библиотека или shared-пакет:

export default defineConfig({
  build: {
    lib: {
      entry: path.resolve(__dirname, 'src/index.ts'),
      name: 'MyLib',
      formats: ['es', 'cjs'],
      fileName: (format) => `index.${format}.js`,
    },
    rollupOptions: {
      external: ['react', 'react-dom'],
      output: {
        globals: { react: 'React', 'react-dom': 'ReactDOM' },
      },
    },
  },
})

Скрипты

{
  "scripts": {
    "dev": "vite",
    "build": "tsc --noEmit && vite build",
    "build:analyze": "ANALYZE=true vite build",
    "preview": "vite preview",
    "lint": "eslint src --ext .ts,.tsx --report-unused-disable-directives"
  }
}

tsc --noEmit перед vite build — проверяем типы перед сборкой. Vite транспилирует TypeScript без проверки типов, поэтому это важно.

Что делаем

Настраиваем vite.config.ts под стек проекта (React/Vue/Svelte), алиасы, proxy на backend, CSS/SCSS, подключаем нужные плагины, оптимизируем manual chunks под характеристики приложения, настраиваем переменные окружения, добавляем bundle visualizer.

Срок: несколько часов для нового проекта, 1 день при переезде с webpack.