**Vite** — это современный инструмент сборки, созданный автором Vue — Эваном Ю. В отличие от Webpack, Vite не собирает весь код перед запуском dev-сервера. Он использует нативные ES-модули браузера: каждый файл отдаётся браузеру напрямую, без бандлинга. Это даёт мгновенный старт даже в больших проектах.
npm create vue@latest my-app
cd my-app
npm install
npm run devКоманда create vue запустит интерактивный мастер, где можно выбрать TypeScript, Vue Router, Pinia, Vitest и другие инструменты.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
// @ теперь указывает на папку src/
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
port: 3000,
open: true, // открыть браузер при старте
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'pinia'],
},
},
},
},
})Vite поддерживает файлы .env, .env.development, .env.production. Переменные доступны только если начинаются с VITE_:
# .env.development
VITE_API_URL=http://localhost:8080/api
VITE_APP_TITLE=Мой сайт (DEV)
# .env.production
VITE_API_URL=https://api.mysite.com
VITE_APP_TITLE=Мой сайтВ коде:
const apiUrl = import.meta.env.VITE_API_URL
const title = import.meta.env.VITE_APP_TITLE
const isDev = import.meta.env.DEV // true в development
const isProd = import.meta.env.PROD // true в production
const mode = import.meta.env.MODE // 'development' или 'production'Команда npm run build запускает Rollup и создаёт оптимизированный бандл в папке dist/:
dist/
├── index.html
└── assets/
├── index-Cx3b1Rg2.js (основной чанк)
├── vendor-BkZ3vD9a.js (vue, vue-router...)
└── index-DpnGxI8u.cssДля анализа размера бандла используй:
npm install -D rollup-plugin-visualizer// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
vue(),
visualizer({ open: true }), // откроет интерактивную карту после build
],
})npm run dev # mode: development
npm run build # mode: production
npx vite --mode staging # mode: staging (читает .env.staging)Vite — это не просто замена Webpack. Благодаря HMR (Hot Module Replacement) изменения в коде отображаются в браузере практически мгновенно, без полной перезагрузки страницы.
Эмуляция работы с переменными окружения и псевдонимами путей — как Vite обрабатывает import.meta.env и алиасы
// ============================================
// Эмуляция import.meta.env из Vite
// ============================================
// В реальном Vite эти значения инжектируются при сборке.
// Здесь мы воспроизводим логику вручную.
function createEnv(mode, rawEnv) {
const filtered = {}
// Vite передаёт в браузер ТОЛЬКО переменные с префиксом VITE_
for (const [key, value] of Object.entries(rawEnv)) {
if (key.startsWith('VITE_')) {
filtered[key] = value
}
}
// Vite также добавляет встроенные переменные
return {
...filtered,
MODE: mode,
DEV: mode !== 'production',
PROD: mode === 'production',
SSR: false,
BASE_URL: '/',
}
}
// Симулируем .env.development
const devRawEnv = {
VITE_API_URL: 'http://localhost:8080/api',
VITE_APP_TITLE: 'Мой сайт (DEV)',
SECRET_KEY: 'this-is-secret', // НЕ начинается с VITE_ — не попадёт в браузер
DATABASE_URL: 'postgres://...', // то же самое
}
// Симулируем .env.production
const prodRawEnv = {
VITE_API_URL: 'https://api.mysite.com',
VITE_APP_TITLE: 'Мой сайт',
SECRET_KEY: 'prod-secret',
DATABASE_URL: 'postgres://prod...',
}
console.log('=== Development окружение ===')
const devEnv = createEnv('development', devRawEnv)
console.log('import.meta.env:', devEnv)
console.log('API URL:', devEnv.VITE_API_URL)
console.log('Is DEV?', devEnv.DEV)
console.log('SECRET_KEY доступен?', 'SECRET_KEY' in devEnv) // false — безопасно
console.log('\n=== Production окружение ===')
const prodEnv = createEnv('production', prodRawEnv)
console.log('import.meta.env:', prodEnv)
console.log('API URL:', prodEnv.VITE_API_URL)
console.log('Is PROD?', prodEnv.PROD)
// ============================================
// Эмуляция алиасов путей (@ -> src/)
// ============================================
console.log('\n=== Разрешение алиасов путей ===')
function createAliasResolver(aliases) {
return function resolvePath(importPath) {
for (const [alias, target] of Object.entries(aliases)) {
if (importPath.startsWith(alias)) {
return importPath.replace(alias, target)
}
}
return importPath // без изменений
}
}
const resolve = createAliasResolver({
'@': '/project/src',
'@components': '/project/src/components',
'@utils': '/project/src/utils',
})
const imports = [
'@/components/Button.vue',
'@/types/user.ts',
'@components/Header.vue',
'@utils/format.ts',
'./relative/path.ts', // относительный путь — не меняется
]
for (const imp of imports) {
console.log(`"${imp}" -> "${resolve(imp)}"`)
}
// ============================================
// Эмуляция manualChunks — разбивка бандла
// ============================================
console.log('\n=== Стратегия разбивки бандла ===')
const modules = [
{ name: 'vue', size: 80 },
{ name: 'vue-router', size: 40 },
{ name: 'pinia', size: 30 },
{ name: 'chart.js', size: 200 },
{ name: 'd3', size: 300 },
{ name: 'App.vue', size: 5 },
{ name: 'HomePage.vue', size: 10 },
{ name: 'api.ts', size: 8 },
]
const manualChunks = {
vendor: ['vue', 'vue-router', 'pinia'],
charts: ['chart.js', 'd3'],
}
function assignChunks(modules, manualChunks) {
const chunks = {}
for (const mod of modules) {
let assigned = false
for (const [chunkName, chunkModules] of Object.entries(manualChunks)) {
if (chunkModules.includes(mod.name)) {
if (!chunks[chunkName]) chunks[chunkName] = { modules: [], totalSize: 0 }
chunks[chunkName].modules.push(mod.name)
chunks[chunkName].totalSize += mod.size
assigned = true
break
}
}
if (!assigned) {
if (!chunks['index']) chunks['index'] = { modules: [], totalSize: 0 }
chunks['index'].modules.push(mod.name)
chunks['index'].totalSize += mod.size
}
}
return chunks
}
const result = assignChunks(modules, manualChunks)
for (const [chunk, info] of Object.entries(result)) {
console.log(`Chunk "${chunk}": ${info.totalSize}KB — [${info.modules.join(', ')}]`)
}**Vite** — это современный инструмент сборки, созданный автором Vue — Эваном Ю. В отличие от Webpack, Vite не собирает весь код перед запуском dev-сервера. Он использует нативные ES-модули браузера: каждый файл отдаётся браузеру напрямую, без бандлинга. Это даёт мгновенный старт даже в больших проектах.
npm create vue@latest my-app
cd my-app
npm install
npm run devКоманда create vue запустит интерактивный мастер, где можно выбрать TypeScript, Vue Router, Pinia, Vitest и другие инструменты.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
plugins: [
vue(),
],
resolve: {
alias: {
// @ теперь указывает на папку src/
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
port: 3000,
open: true, // открыть браузер при старте
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
},
},
},
build: {
outDir: 'dist',
sourcemap: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['vue', 'vue-router', 'pinia'],
},
},
},
},
})Vite поддерживает файлы .env, .env.development, .env.production. Переменные доступны только если начинаются с VITE_:
# .env.development
VITE_API_URL=http://localhost:8080/api
VITE_APP_TITLE=Мой сайт (DEV)
# .env.production
VITE_API_URL=https://api.mysite.com
VITE_APP_TITLE=Мой сайтВ коде:
const apiUrl = import.meta.env.VITE_API_URL
const title = import.meta.env.VITE_APP_TITLE
const isDev = import.meta.env.DEV // true в development
const isProd = import.meta.env.PROD // true в production
const mode = import.meta.env.MODE // 'development' или 'production'Команда npm run build запускает Rollup и создаёт оптимизированный бандл в папке dist/:
dist/
├── index.html
└── assets/
├── index-Cx3b1Rg2.js (основной чанк)
├── vendor-BkZ3vD9a.js (vue, vue-router...)
└── index-DpnGxI8u.cssДля анализа размера бандла используй:
npm install -D rollup-plugin-visualizer// vite.config.ts
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
plugins: [
vue(),
visualizer({ open: true }), // откроет интерактивную карту после build
],
})npm run dev # mode: development
npm run build # mode: production
npx vite --mode staging # mode: staging (читает .env.staging)Vite — это не просто замена Webpack. Благодаря HMR (Hot Module Replacement) изменения в коде отображаются в браузере практически мгновенно, без полной перезагрузки страницы.
Эмуляция работы с переменными окружения и псевдонимами путей — как Vite обрабатывает import.meta.env и алиасы
// ============================================
// Эмуляция import.meta.env из Vite
// ============================================
// В реальном Vite эти значения инжектируются при сборке.
// Здесь мы воспроизводим логику вручную.
function createEnv(mode, rawEnv) {
const filtered = {}
// Vite передаёт в браузер ТОЛЬКО переменные с префиксом VITE_
for (const [key, value] of Object.entries(rawEnv)) {
if (key.startsWith('VITE_')) {
filtered[key] = value
}
}
// Vite также добавляет встроенные переменные
return {
...filtered,
MODE: mode,
DEV: mode !== 'production',
PROD: mode === 'production',
SSR: false,
BASE_URL: '/',
}
}
// Симулируем .env.development
const devRawEnv = {
VITE_API_URL: 'http://localhost:8080/api',
VITE_APP_TITLE: 'Мой сайт (DEV)',
SECRET_KEY: 'this-is-secret', // НЕ начинается с VITE_ — не попадёт в браузер
DATABASE_URL: 'postgres://...', // то же самое
}
// Симулируем .env.production
const prodRawEnv = {
VITE_API_URL: 'https://api.mysite.com',
VITE_APP_TITLE: 'Мой сайт',
SECRET_KEY: 'prod-secret',
DATABASE_URL: 'postgres://prod...',
}
console.log('=== Development окружение ===')
const devEnv = createEnv('development', devRawEnv)
console.log('import.meta.env:', devEnv)
console.log('API URL:', devEnv.VITE_API_URL)
console.log('Is DEV?', devEnv.DEV)
console.log('SECRET_KEY доступен?', 'SECRET_KEY' in devEnv) // false — безопасно
console.log('\n=== Production окружение ===')
const prodEnv = createEnv('production', prodRawEnv)
console.log('import.meta.env:', prodEnv)
console.log('API URL:', prodEnv.VITE_API_URL)
console.log('Is PROD?', prodEnv.PROD)
// ============================================
// Эмуляция алиасов путей (@ -> src/)
// ============================================
console.log('\n=== Разрешение алиасов путей ===')
function createAliasResolver(aliases) {
return function resolvePath(importPath) {
for (const [alias, target] of Object.entries(aliases)) {
if (importPath.startsWith(alias)) {
return importPath.replace(alias, target)
}
}
return importPath // без изменений
}
}
const resolve = createAliasResolver({
'@': '/project/src',
'@components': '/project/src/components',
'@utils': '/project/src/utils',
})
const imports = [
'@/components/Button.vue',
'@/types/user.ts',
'@components/Header.vue',
'@utils/format.ts',
'./relative/path.ts', // относительный путь — не меняется
]
for (const imp of imports) {
console.log(`"${imp}" -> "${resolve(imp)}"`)
}
// ============================================
// Эмуляция manualChunks — разбивка бандла
// ============================================
console.log('\n=== Стратегия разбивки бандла ===')
const modules = [
{ name: 'vue', size: 80 },
{ name: 'vue-router', size: 40 },
{ name: 'pinia', size: 30 },
{ name: 'chart.js', size: 200 },
{ name: 'd3', size: 300 },
{ name: 'App.vue', size: 5 },
{ name: 'HomePage.vue', size: 10 },
{ name: 'api.ts', size: 8 },
]
const manualChunks = {
vendor: ['vue', 'vue-router', 'pinia'],
charts: ['chart.js', 'd3'],
}
function assignChunks(modules, manualChunks) {
const chunks = {}
for (const mod of modules) {
let assigned = false
for (const [chunkName, chunkModules] of Object.entries(manualChunks)) {
if (chunkModules.includes(mod.name)) {
if (!chunks[chunkName]) chunks[chunkName] = { modules: [], totalSize: 0 }
chunks[chunkName].modules.push(mod.name)
chunks[chunkName].totalSize += mod.size
assigned = true
break
}
}
if (!assigned) {
if (!chunks['index']) chunks['index'] = { modules: [], totalSize: 0 }
chunks['index'].modules.push(mod.name)
chunks['index'].totalSize += mod.size
}
}
return chunks
}
const result = assignChunks(modules, manualChunks)
for (const [chunk, info] of Object.entries(result)) {
console.log(`Chunk "${chunk}": ${info.totalSize}KB — [${info.modules.join(', ')}]`)
}Напиши функцию `parseEnvFile(content, mode)`, которая принимает строку содержимого .env файла и режим (mode). Функция должна: 1) распарсить строки вида KEY=VALUE (игнорируя комментарии, начинающиеся с #, и пустые строки); 2) вернуть объект только с теми ключами, которые начинаются с "VITE_"; 3) добавить поле MODE со значением переданного mode.
Используй content.split("\n") для разбивки на строки. Для каждой строки: trim(), затем проверь line.startsWith("#") или line === "". Для KEY=VALUE используй indexOf("=") чтобы найти первый знак равенства, затем substring(). Проверяй key.startsWith("VITE_").
Токены для AI-помощника закончились
Купи токены чтобы задавать вопросы AI прямо в уроке