11. Multi-page приложения
По умолчанию Vite настроен для SPA с одним entry point. Но он также отлично справляется с Multi-Page Applications — приложениями с несколькими независимыми HTML страницами.
Структура MPA проекта
Заголовок раздела «Структура MPA проекта»my-mpa/├── index.html ← Главная страница├── about/│ └── index.html ← Страница /about/├── admin/│ └── index.html ← Страница /admin/├── src/│ ├── main.ts ← Entry для главной│ ├── about.ts ← Entry для about│ └── admin.ts ← Entry для admin└── vite.config.tsКонфигурация MPA
Заголовок раздела «Конфигурация MPA»import { defineConfig } from 'vite'import { resolve } from 'path'
export default defineConfig({ build: { rollupOptions: { input: { // Явно указываем каждый entry point main: resolve(__dirname, 'index.html'), about: resolve(__dirname, 'about/index.html'), admin: resolve(__dirname, 'admin/index.html'), }, }, },})HTML файлы страниц
Заголовок раздела «HTML файлы страниц»<!-- index.html — главная страница --><!DOCTYPE html><html> <head><title>Главная</title></head> <body> <div id="root"></div> <script type="module" src="/src/main.ts"></script> </body></html>
<!-- about/index.html — страница About --><!DOCTYPE html><html> <head><title>О нас</title></head> <body> <div id="root"></div> <script type="module" src="/src/about.ts"></script> </body></html>Автоматическое определение страниц
Заголовок раздела «Автоматическое определение страниц»// vite.config.ts — автоматически найти все index.htmlimport { defineConfig } from 'vite'import { glob } from 'glob'import { resolve } from 'path'
function getInputs() { const htmlFiles = glob.sync('**/index.html', { ignore: ['node_modules/**', 'dist/**'], })
return Object.fromEntries( htmlFiles.map(file => [ file.replace('/index.html', '').replace('index.html', 'main'), resolve(__dirname, file), ]) )}
export default defineConfig({ build: { rollupOptions: { input: getInputs(), }, },})Shared Assets между страницами
Заголовок раздела «Shared Assets между страницами»// src/shared.ts — общий код для всех страницexport const analytics = { track: (event: string) => { // GA, Mixpanel и т.д. },}
// src/main.tsimport { analytics } from './shared'import { initHomePage } from './pages/home'analytics.track('page_view')initHomePage()
// src/about.tsimport { analytics } from './shared'import { initAboutPage } from './pages/about'analytics.track('page_view')initAboutPage()Output структура MPA
Заголовок раздела «Output структура MPA»dist/├── index.html ← Главная├── about/│ └── index.html ← About страница├── admin/│ └── index.html ← Admin страница└── assets/ ├── main-BxS1.js ← Entry для главной ├── about-DtS3.js ← Entry для about ├── admin-xyz.js ← Entry для admin ├── shared-abc.js ← Общий чанк (автоматически!) └── styles-def.css ← CSSMPA vs SPA: Когда использовать
Заголовок раздела «MPA vs SPA: Когда использовать»MPA подходит для:✓ Маркетинговые сайты с несколькими отдельными страницами✓ Административные панели с разными entry points✓ Микрофронтенды (отдельные приложения на одном домене)✓ Постепенная миграция с традиционных MPA на Vite
SPA подходит для:✓ Полноценные веб-приложения с клиентским роутингом✓ React Router, Vue Router, TanStack Router✓ Rich interactive experiencesНиже — интерактивный исследователь структуры MPA: настраивай страницы и смотри конфигурацию: