Vite использует конфигурационный файл для управления поведением dev-сервера, системы сборки, плагинов, алиасов, переменных окружения, CSS-препроцессоров, Rollup-настроек и других аспектов проекта.
По умолчанию Vite ищет конфигурацию в корне проекта. Поддерживаются несколько форматов:
vite.config.jsvite.config.mjsvite.config.tsvite.config.cjsvite.config.mtsvite.config.ctsНаиболее распространёнными считаются:
.js).ts).mjs)Файл vite.config.js является самым простым вариантом
конфигурации.
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 3000
}
})
Vite автоматически загружает этот файл при запуске команд:
vite
vite dev
vite build
vite preview
Функция defineConfig() не является обязательной, однако
она предоставляет несколько преимуществ:
Без defineConfig() конфигурация также работает:
export default {
server: {
port: 3000
}
}
Но IDE теряет часть информации о типах.
Исторически Node.js использовал систему CommonJS:
const path = require('path')
module.exports = {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
}
Современный Vite ориентирован на ES Modules.
Поэтому чаще используется синтаксис:
import path from 'path'
export default {
resolve: {
alias: {
'@': path.resolve('src')
}
}
}
Поведение файла .js зависит от поля type в
package.json.
{
"type": "commonjs"
}
или отсутствие поля type.
Тогда .js трактуется как CommonJS.
{
"type": "module"
}
Тогда .js считается ES Module.
Это напрямую влияет на работу vite.config.js.
Если проект работает в режиме CommonJS, а конфигурация написана как ES Module:
import { defineConfig } from 'vite'
export default defineConfig({})
Node.js выдаст ошибку:
Cannot use import statement outside a module
Формат .js подходит в случаях:
Расширение .mjs принудительно указывает Node.js, что
файл является ES Module независимо от поля type.
Файл:
vite.config.mjs
всегда работает как ES Module.
import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
resolve: {
alias: {
'@': path.resolve('src')
}
}
})
Главное преимущество — предсказуемость.
Даже если в package.json отсутствует:
{
"type": "module"
}
конфигурация всё равно будет работать как ES Module.
В больших monorepo разные пакеты могут использовать:
.mjs устраняет неоднозначность.
Во многих legacy-проектах используется CommonJS:
require()
module.exports
Но Vite лучше работает с ESM.
В этом случае удобно оставить проект на CommonJS, а Vite-конфигурацию
вынести в .mjs.
Поведение зависит от:
"type": "module"
Всегда:
import/export
без зависимости от package.json.
Внутри .mjs недоступны CommonJS-глобалы:
__dirname
__filename
require
module.exports
Вместо __dirname используется:
import { fileURLToPath } from 'url'
import { dirname } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
Полный пример:
import { defineConfig } from 'vite'
import { fileURLToPath } from 'url'
import { dirname, resolve } from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
export default defineConfig({
resolve: {
alias: {
'@': resolve(__dirname, 'src')
}
}
})
Файл:
vite.config.ts
позволяет писать конфигурацию на TypeScript.
Преимущества:
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 3000
}
})
На первый взгляд код почти не отличается от JavaScript.
Но теперь TypeScript проверяет корректность конфигурации.
Например:
export default defineConfig({
server: {
port: '3000'
}
})
IDE сразу покажет ошибку:
Type 'string' is not assignable to type 'number'
TypeScript особенно полезен при подключении сложных плагинов.
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [vue()]
})
IDE понимает типы:
Vite позволяет экспортировать функцию:
import { defineConfig } from 'vite'
export default defineConfig(({ mode }) => {
return {
server: {
port: mode === 'development'
? 3000
: 8080
}
}
})
TypeScript знает типы аргументов:
import { defineConfig } from 'vite'
export default defineConfig(({ command, mode }) => {
console.log(command)
console.log(mode)
return {}
})
Может быть:
'serve'
или:
'build'
Обычно:
development
production
или пользовательские режимы:
vite --mode staging
Нет.
Vite автоматически обрабатывает TypeScript-конфигурацию.
Дополнительная настройка обычно не требуется.
Внутри используется механизм трансформации TypeScript в JavaScript перед выполнением.
При запуске:
vite
происходит:
vite.config.tsКонфигурация выполняется в Node.js, а не в браузере.
Недоступны:
window
document
localStorage
Файл vite.config.ts — это backend-код среды Node.js.
Он не попадает в браузерный bundle.
Файл:
vite.config.mts
является TypeScript-версией .mjs.
Он всегда работает как ES Module.
Поведение зависит от настроек TypeScript и Node.js.
Всегда ESM.
.mts полезен при:
Принудительный CommonJS:
const { defineConfig } = require('vite')
module.exports = defineConfig({
server: {
port: 3000
}
})
TypeScript + CommonJS:
import { defineConfig } from 'vite'
export = defineConfig({
server: {
port: 3000
}
})
При запуске Vite ищет конфигурацию в определённом порядке.
Например:
vite.config.ts
vite.config.mts
vite.config.js
vite.config.mjs
Точный внутренний приоритет зависит от версии Vite.
Можно выбрать файл вручную:
vite --config vite.admin.config.ts
В крупных проектах встречаются:
vite.client.config.ts
vite.admin.config.ts
vite.ssr.config.ts
Запуск:
vite build --config vite.ssr.config.ts
Подходит для:
Плюсы:
Минусы:
Подходит для:
Плюсы:
Минусы:
Подходит для:
Плюсы:
Минусы:
__dirnameПодходит для:
Плюсы:
Минусы:
Конфигурация может быть динамической.
import { defineConfig } from 'vite'
export default defineConfig(({ command, mode }) => {
const isBuild = command === 'build'
return {
build: {
sourcemap: !isBuild
}
}
})
Поддерживается async-конфигурация.
import { defineConfig } from 'vite'
export default defineConfig(async () => {
const data = await loadConfig()
return {
define: {
CONFIG: JSON.stringify(data)
}
}
})
async function loadConfig() {
return {
api: 'https://api.site.com'
}
}
В ESM-конфигурациях активно используется:
import.meta.url
Пример:
import { fileURLToPath } from 'url'
const filename = fileURLToPath(import.meta.url)
Это замена старых CommonJS-механизмов.
Современные версии Vite ориентированы на актуальные версии Node.js.
Особенно это важно для:
.mjs.mtsimport.meta.urlСтарые версии Node.js могут некорректно работать с модульной системой ES Modules.
Наиболее распространённая конфигурация современных проектов:
// vite.config.ts
import { defineConfig } from 'vite'
export default defineConfig({
server: {
port: 5173
}
})
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
},
server: {
port: Number(env.VITE_PORT)
},
build: {
sourcemap: mode === 'development'
}
}
})
Ошибка:
const path = require('path')
export default {}
Нельзя смешивать:
requireexport defaultОшибка:
console.log(__dirname)
в .mjs или .mts.
Конфликт:
{
"type": "commonjs"
}
при использовании ESM-конфигурации.
Ошибка:
localStorage.getItem('token')
Конфигурация запускается в Node.js, а не в браузере.
Оптимальный вариант:
vite.config.ts
Лучше использовать:
vite.config.mjs
или:
vite.config.mts
Подходят:
vite.config.cjs
или:
vite.config.mjs
в зависимости от архитектуры проекта.
Формат конфигурации практически не влияет на скорость работы Vite.
Разница между:
.js.ts.mjs.mtsобычно незначительна.
Основное различие связано: