Vite — React + TypeScript + MobX
Что такое Vite?
Заголовок раздела «Что такое Vite?»Vite — современный build tool использующий нативные ES modules в development (почти мгновенный старт) и Rollup для production bundle. Разработан Evan You (автор Vue.js), но отлично работает с React.
Ключевые преимущества:
- Dev server: старт за < 300ms (vs webpack 15-30 сек на большом проекте)
- HMR (Hot Module Replacement): обновление < 50ms
- Production: Rollup-based оптимизированный bundle
Создание проекта — пошаговый guide
Заголовок раздела «Создание проекта — пошаговый guide»Шаг 1: Инициализация
Заголовок раздела «Шаг 1: Инициализация»npm create vite@latest my-react-app -- --template react-tscd my-react-appnpm installСтруктура после создания:
my-react-app/ public/ vite.svg src/ assets/ App.css App.tsx index.css main.tsx vite-env.d.ts index.html package.json tsconfig.json tsconfig.node.json vite.config.tsШаг 2: Установка зависимостей
Заголовок раздела «Шаг 2: Установка зависимостей»# MobX + React интеграцияnpm install mobx mobx-react-lite
# Роутерnpm install react-router-dom
# Dev зависимостиnpm install -D @types/nodeШаг 3: Настройка vite.config.ts
Заголовок раздела «Шаг 3: Настройка vite.config.ts»import { defineConfig } from 'vite';import react from '@vitejs/plugin-react';import path from 'path';
export default defineConfig({ plugins: [react()], resolve: { alias: { '@': path.resolve(__dirname, './src'), '@components': path.resolve(__dirname, './src/components'), '@stores': path.resolve(__dirname, './src/stores'), '@hooks': path.resolve(__dirname, './src/hooks'), '@types': path.resolve(__dirname, './src/types'), }, }, server: { port: 3000, open: true, proxy: { // Проксирование API запросов '/api': { target: 'http://localhost:4000', changeOrigin: true, rewrite: path => path.replace(/^\/api/, ''), }, }, }, build: { outDir: 'dist', sourcemap: true, rollupOptions: { output: { // Разбивка на чанки manualChunks: { vendor: ['react', 'react-dom'], mobx: ['mobx', 'mobx-react-lite'], router: ['react-router-dom'], }, }, }, },});Шаг 4: tsconfig.json — строгая типизация
Заголовок раздела «Шаг 4: tsconfig.json — строгая типизация»{ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, "lib": ["ES2020", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true,
/* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx",
/* Строгий режим */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true,
/* Path aliases */ "baseUrl": ".", "paths": { "@/*": ["src/*"], "@components/*": ["src/components/*"], "@stores/*": ["src/stores/*"], "@hooks/*": ["src/hooks/*"] },
/* MobX decorators */ "experimentalDecorators": true, "useDefineForClassFields": false }, "include": ["src"], "references": [{ "path": "./tsconfig.node.json" }]}Шаг 5: Структура проекта MobX
Заголовок раздела «Шаг 5: Структура проекта MobX»src/ components/ ui/ — кнопки, инпуты, спиннеры layout/ — Header, Footer, Layout features/ — компоненты функций приложения stores/ AuthStore.ts UserStore.ts RootStore.ts index.ts — export + Context Provider hooks/ useStores.ts — хук для доступа к сторам services/ api.ts — fetch wrapper authService.ts types/ index.ts pages/ HomePage.tsx ProfilePage.tsx App.tsx main.tsxШаг 6: Настройка MobX
Заголовок раздела «Шаг 6: Настройка MobX»import { AuthStore } from './AuthStore';import { UserStore } from './UserStore';
export class RootStore { auth: AuthStore; users: UserStore;
constructor() { this.auth = new AuthStore(this); this.users = new UserStore(this); }}
// src/stores/index.tsimport React, { createContext, useContext, useState } from 'react';import { RootStore } from './RootStore';
const StoreContext = createContext<RootStore | null>(null);
export function StoreProvider({ children }: React.PropsWithChildren) { const [store] = useState(() => new RootStore()); return <StoreContext.Provider value={store}>{children}</StoreContext.Provider>;}
export function useStores(): RootStore { const store = useContext(StoreContext); if (!store) throw new Error('useStores must be used within StoreProvider'); return store;}Шаг 7: main.tsx
Заголовок раздела «Шаг 7: main.tsx»import React from 'react';import ReactDOM from 'react-dom/client';import { BrowserRouter } from 'react-router-dom';import { StoreProvider } from '@stores';import App from './App';import './index.css';
ReactDOM.createRoot(document.getElementById('root')!).render( <React.StrictMode> <BrowserRouter> <StoreProvider> <App /> </StoreProvider> </BrowserRouter> </React.StrictMode>);Полезные команды
Заголовок раздела «Полезные команды»npm run dev # dev server на localhost:3000npm run build # production build в dist/npm run preview # preview production buildnpm run typecheck # только typecheck (без build){ "scripts": { "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", "typecheck": "tsc --noEmit" }}Environment variables
Заголовок раздела «Environment variables»VITE_API_URL=http://localhost:4000VITE_APP_TITLE=My App
# .env.productionVITE_API_URL=https://api.example.com// Использование — только переменные с VITE_ prefix доступны в браузереconst apiUrl = import.meta.env.VITE_API_URL;const isDev = import.meta.env.DEV;const isProd = import.meta.env.PROD;