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
70 lines
No EOL
2.2 KiB
TypeScript
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 },
|
|
},
|
|
},
|
|
}) |