11faf086a4
До: 1 chunk index-XXX.js 2 МБ / 703 КБ gzip — любой commit инвалидирует весь. После: 10 chunks. Vendor стабилен и кэшируется, при правке кода только main (18 КБ gz) перезагружается: vendor-react 194 / 60 gz (rare changes) vendor-tanstack 127 / 40 gz vendor-forms 145 / 46 gz (react-hook-form + ajv) vendor-nstart-ui 1229 /465 gz (corp UI — brand assets + stickers) vendor-icons 62 / 13 gz (phosphor) vendor-auth 72 / 19 gz (oidc-client-ts + react-oidc-context) vendor-i18n 56 / 18 gz vendor-net 42 / 17 gz (axios + crypto) vendor-misc 15 / 6 gz index (main) 67 / 19 gz ← наш код vendor-nstart-ui всё ещё 465 КБ gz — доминирует. Это brand assets (stickers, lottie animations) которые eager-imported в библиотеке. Дальнейший win требует tree-shaking в @nstart/ui — отдельная задача.
75 lines
2.6 KiB
TypeScript
75 lines
2.6 KiB
TypeScript
import { defineConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
|
|
import path from 'path'
|
|
|
|
export default defineConfig({
|
|
plugins: [
|
|
TanStackRouterVite({ routesDirectory: 'src/routes', generatedRouteTree: 'src/routeTree.gen.ts' }),
|
|
react(),
|
|
tailwindcss(),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, 'src'),
|
|
},
|
|
},
|
|
server: {
|
|
host: '0.0.0.0',
|
|
port: 5173,
|
|
proxy: {
|
|
'/api': {
|
|
target: process.env.VITE_API_PROXY ?? 'http://localhost:8080',
|
|
changeOrigin: true,
|
|
},
|
|
},
|
|
},
|
|
build: {
|
|
chunkSizeWarningLimit: 600,
|
|
rollupOptions: {
|
|
output: {
|
|
// Группировка по принципу: что меняется редко → отдельный chunk →
|
|
// браузер кэширует надолго. Что меняется часто (наш код) — в main.
|
|
manualChunks: (id) => {
|
|
if (!id.includes('node_modules')) return undefined
|
|
|
|
// React core — стабильный, основа всего
|
|
if (id.match(/node_modules\/(react|react-dom|scheduler)\//)) return 'vendor-react'
|
|
|
|
// TanStack — Router + Query, крупные но стабильные
|
|
if (id.includes('node_modules/@tanstack/')) return 'vendor-tanstack'
|
|
|
|
// @nstart/ui — самый тяжёлый: brand stickers/animations + tons of UI
|
|
// (проверяй динамически: lottie, echarts если есть, motion)
|
|
if (id.includes('node_modules/@nstart/ui')) return 'vendor-nstart-ui'
|
|
|
|
// Иконки — отдельно, ленивая загрузка эффективна
|
|
if (id.includes('node_modules/@phosphor-icons/')) return 'vendor-icons'
|
|
|
|
// Формы + JSON Schema валидация
|
|
if (id.match(/node_modules\/(react-hook-form|@hookform|ajv|ajv-formats)\//)) {
|
|
return 'vendor-forms'
|
|
}
|
|
|
|
// OIDC / auth
|
|
if (id.match(/node_modules\/(oidc-client-ts|react-oidc-context)\//)) {
|
|
return 'vendor-auth'
|
|
}
|
|
|
|
// i18next — отдельно
|
|
if (id.match(/node_modules\/(i18next|react-i18next|i18next-browser-languagedetector)\//)) {
|
|
return 'vendor-i18n'
|
|
}
|
|
|
|
// Axios + парсеры
|
|
if (id.match(/node_modules\/(axios|jose|crypto-js)\//)) return 'vendor-net'
|
|
|
|
// Остальное — в общий vendor (не должно быть много)
|
|
return 'vendor-misc'
|
|
},
|
|
},
|
|
},
|
|
},
|
|
})
|