Конфигурация в Vite может изменяться в зависимости от:
serve или build);development, production,
staging, test и любых пользовательских
режимов);Такой подход позволяет использовать один файл конфигурации для разных сценариев:
В отличие от статических конфигураций, Vite поддерживает программное формирование настроек через функции и динамические условия.
Файл vite.config.js или vite.config.ts
может экспортировать не объект, а функцию.
Простейший пример:
import { defineConfig } from 'vite'
export default defineConfig(({ command, mode }) => {
return {
server: {
port: command === 'serve' ? 5173 : 4173
}
}
})
Vite передаёт в функцию объект контекста, содержащий:
| Поле | Назначение |
|---|---|
command |
Текущая команда |
mode |
Активный режим |
isSsrBuild |
SSR-сборка |
isPreview |
Режим preview |
Существует два основных значения:
| Значение | Команда |
|---|---|
serve |
vite, vite dev |
build |
vite build |
export default defineConfig(({ command }) => {
if (command === 'serve') {
return {
server: {
open: true
}
}
}
return {
build: {
sourcemap: false
}
}
})
Во время разработки и production-сборки часто требуются разные плагины.
import legacy from '@vitejs/plugin-legacy'
import vue from '@vitejs/plugin-vue'
export default defineConfig(({ command }) => {
return {
plugins: [
vue(),
command === 'build' && legacy()
].filter(Boolean)
}
})
Здесь:
vue() подключается всегда;legacy() только при production-сборке.Некоторые секции конфигурации актуальны только для конкретной команды.
export default defineConfig(({ command }) => {
if (command === 'serve') {
return {
server: {
host: '0.0.0.0',
port: 3000,
open: true
}
}
}
return {}
})
export default defineConfig(({ command }) => {
if (command === 'build') {
return {
build: {
minify: 'esbuild',
sourcemap: true
}
}
}
return {}
})
mode определяет активный режим работы приложения.
По умолчанию:
| Команда | Режим |
|---|---|
vite |
development |
vite build |
production |
vite build --mode staging
Тогда:
export default defineConfig(({ mode }) => {
console.log(mode)
})
Выведет:
staging
export default defineConfig(({ mode }) => {
return {
base: mode === 'production'
? '/production/'
: '/'
}
})
export default defineConfig(({ mode }) => {
return {
define: {
__API_URL__: JSON.stringify(
mode === 'production'
? 'https://api.site.com'
: 'http://localhost:3001'
)
}
}
})
vite build --mode staging
Конфигурация:
export default defineConfig(({ mode }) => {
return {
build: {
sourcemap: mode === 'staging'
}
}
})
export default defineConfig(({ mode }) => {
const config = {
development: {
api: 'http://localhost:3000'
},
staging: {
api: 'https://staging-api.site.com'
},
production: {
api: 'https://api.site.com'
}
}
return {
define: {
__API__: JSON.stringify(config[mode].api)
}
}
})
Vite предоставляет функцию loadEnv.
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
server: {
port: Number(env.VITE_PORT)
}
}
})
Vite автоматически поддерживает:
| Файл | Назначение |
|---|---|
.env |
Общие переменные |
.env.local |
Локальные переменные |
.env.development |
Development |
.env.production |
Production |
.env.staging |
Пользовательский режим |
.env.productionVITE_API_URL=https://api.site.com
VITE_PORT=8080
.env.developmentVITE_API_URL=http://localhost:3000
VITE_PORT=5173
В браузерный код попадают только переменные, начинающиеся с
VITE_.
Допустим:
VITE_API_URL=https://api.site.com
SECRET_KEY=123456
В клиентском коде:
console.log(import.meta.env.VITE_API_URL)
Работает.
Но:
console.log(import.meta.env.SECRET_KEY)
Не работает.
Это механизм защиты приватных переменных.
import path from 'path'
export default defineConfig(({ mode }) => {
return {
resolve: {
alias: {
'@api': mode === 'mock'
? path.resolve(__dirname, 'src/api/mock')
: path.resolve(__dirname, 'src/api/real')
}
}
}
})
export default defineConfig(({ command }) => {
return {
optimizeDeps: {
include: command === 'serve'
? ['lodash']
: []
}
}
})
export default defineConfig(({ mode }) => {
return {
build: {
minify: mode === 'development'
? false
: 'esbuild'
}
}
})
export default defineConfig(({ mode }) => {
return {
build: {
sourcemap:
mode === 'staging' ||
mode === 'development'
}
}
})
export default defineConfig(({ mode }) => {
return {
build: {
outDir:
mode === 'production'
? 'dist'
: 'dist-test'
}
}
})
export default defineConfig(({ mode }) => {
const targets = {
development: 'http://localhost:3000',
staging: 'https://staging-api.site.com',
production: 'https://api.site.com'
}
return {
server: {
proxy: {
'/api': {
target: targets[mode],
changeOrigin: true
}
}
}
}
})
export default defineConfig(({ mode }) => {
return {
define: {
__DEV__: mode === 'development',
__PROD__: mode === 'production'
}
}
})
Использование:
if (__DEV__) {
console.log('debug')
}
Во время сборки Vite заменяет значения статически.
Крупные проекты обычно разделяют конфигурацию.
Структура:
config/
vite.base.js
vite.dev.js
vite.prod.js
// vite.base.js
export const baseConfig = {
resolve: {
alias: {
'@': '/src'
}
}
}
// vite.dev.js
export const devConfig = {
server: {
port: 3000
}
}
// vite.prod.js
export const prodConfig = {
build: {
minify: 'esbuild'
}
}
import { defineConfig, mergeConfig } from 'vite'
import { baseConfig } from './config/vite.base'
import { devConfig } from './config/vite.dev'
import { prodConfig } from './config/vite.prod'
export default defineConfig(({ command }) => {
if (command === 'serve') {
return mergeConfig(baseConfig, devConfig)
}
return mergeConfig(baseConfig, prodConfig)
})
mergeConfig корректно объединяет:
Пример:
import { mergeConfig } from 'vite'
const a = {
server: {
port: 3000
}
}
const b = {
build: {
sourcemap: true
}
}
const result = mergeConfig(a, b)
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig(({ mode }) => {
return {
plugins: [
mode === 'analyze' &&
visualizer({
open: true
})
].filter(Boolean)
}
})
Запуск:
vite build --mode analyze
export default defineConfig(({ isSsrBuild }) => {
return {
build: {
minify: !isSsrBuild
}
}
})
export default defineConfig(({ isSsrBuild }) => {
return {
ssr: {
external: isSsrBuild
? ['mysql2']
: []
}
}
})
export default defineConfig(() => {
const isDocker =
process.env.DOCKER === 'true'
return {
server: {
host: isDocker
? '0.0.0.0'
: 'localhost'
}
}
})
export default defineConfig(({ mode, command }) => {
const isDev =
mode === 'development'
const isBuild =
command === 'build'
return {
build: {
sourcemap:
isDev && isBuild
}
}
})
Большие конфигурации часто используют промежуточные флаги.
export default defineConfig(({ mode, command }) => {
const isDev =
mode === 'development'
const isProd =
mode === 'production'
const isServe =
command === 'serve'
const isBuild =
command === 'build'
return {
server: {
open: isServe
},
build: {
minify: isProd
}
}
})
Такой подход:
Vite поддерживает асинхронные конфигурации.
export default defineConfig(async ({ mode }) => {
const config =
await loadRemoteConfig(mode)
return {
define: {
__REMOTE_CONFIG__:
JSON.stringify(config)
}
}
})
import { defineConfig } from 'vite'
import type { UserConfig } from 'vite'
export default defineConfig(
({ mode }): UserConfig => {
return {
build: {
sourcemap:
mode === 'development'
}
}
}
)
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd())
const isProd = mode === 'production'
const isDev = mode === 'development'
const isBuild = command === 'build'
return {
plugins: [
vue()
],
base: isProd
? '/app/'
: '/',
server: {
port: Number(env.VITE_PORT)
},
build: {
sourcemap: isDev,
minify: isProd,
outDir: isProd
? 'dist'
: 'dist-dev'
},
define: {
__APP_VERSION__:
JSON.stringify(process.env.npm_package_version)
},
css: {
devSourcemap: isDev
}
}
})