rmi-frontend/vite.config.ts
cryptorugmunch 19a7b29e33 feat: add TypeScript strict mode, vitest, zod env validation, playwright, Makefile, .editorconfig
10 improvements to the frontend dev experience:

1. TypeScript strict mode enabled (tsconfig.app.json)
   - strict: true, noImplicitAny: true, noUnusedLocals: true
   - noUnusedParameters: true, noImplicitReturns: true
   - noUncheckedIndexedAccess: true
   - Passes with 0 errors

2. Vitest configured with jsdom + @testing-library/react
   - vitest.config.ts with coverage provider
   - src/test/setup.ts stubs all env vars
   - src/App.test.tsx: smoke test (renders without crash)
   - 1 test passing

3. .editorconfig added (matches biome: 2-space, lf, 120 cols)

4. Makefile added with standard targets:
   make install/dev/build/lint/format/check/typecheck/test/ci/clean

5. Zod env validation (src/lib/env.ts)
   - All import.meta.env calls validated via zod schema
   - Fails fast with clear error if env vars are invalid
   - src/lib/config.ts re-exports from validated env

6. Playwright E2E config + smoke tests
   - playwright.config.ts with chromium
   - e2e/smoke.spec.ts: homepage + navigation tests

7. CI workflow now blocking on lint + typecheck + test + build
   - Removed continue-on-error from lint step
   - Added vitest run step
   - Added tsc --noEmit step

8. rollup-plugin-visualizer added to vite.config.ts
   - Generates dist/stats.html on build

9. Pre-commit hook updated with --staged flag
   - Only lints staged files, not entire repo

10. Removed broken .clinerules symlink

Build: 18s, 0 TS errors, 1 test passing, 0 format errors
2026-07-02 12:28:06 +02:00

70 lines
No EOL
2.2 KiB
TypeScript

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tsconfigPaths from 'vite-tsconfig-paths'
import { visualizer } from 'rollup-plugin-visualizer'
import path from 'path'
export default defineConfig({
plugins: [
react(),
tsconfigPaths(),
visualizer({
filename: 'dist/stats.html',
open: false,
gzipSize: true,
brotliSize: true,
}),
{
name: 'cf-bypass',
transformIndexHtml(html) {
return html.replace(
/<script(?!.*data-cfasync)/g,
'<script data-cfasync="false"'
);
},
},
],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
extensions: ['.js', '.ts', '.tsx', '.json'],
},
optimizeDeps: {
include: ['framer-motion', 'react-router-dom', 'lucide-react'],
},
build: {
target: 'es2020',
chunkSizeWarningLimit: 500,
rollupOptions: {
output: {
manualChunks(id) {
if (id.includes('node_modules')) {
if (id.includes('recharts') || id.includes('lightweight-charts') || id.includes('echarts')) return 'charts'
if (id.includes('cytoscape')) return 'cytoscape'
if (id.includes('framer-motion')) return 'framer'
if (id.includes('lucide-react')) return 'icons'
if (id.includes('react-router') || id.includes('react-dom') || id.includes('react/')) return 'react'
if (id.includes('@radix-ui')) return 'radix'
if (id.includes('@tanstack')) return 'tanstack'
if (id.includes('date-fns') || id.includes('date-fns-tz')) return 'date'
return 'vendor';
}
},
entryFileNames: 'assets/[name]-[hash:8].js',
chunkFileNames: 'assets/[name]-[hash:8].js',
assetFileNames: 'assets/[name]-[hash:8][extname]',
},
},
},
server: {
port: 5173,
host: true,
proxy: {
'/api': { target: 'http://localhost:8000', changeOrigin: true, secure: false },
'/auth': { target: 'http://localhost:8000', changeOrigin: true, secure: false },
'/static': { target: 'http://localhost:8000', changeOrigin: true, secure: false },
'/ws': { target: 'http://localhost:8000', changeOrigin: true, secure: false, ws: true },
},
},
})