- Aligne la configuration avec Playwright - Port 5173 est le port par défaut de Vite - Corrige les tests E2E qui s'attendent à 5173
143 lines
No EOL
4.4 KiB
TypeScript
143 lines
No EOL
4.4 KiB
TypeScript
/// <reference types="vitest" />
|
|
import { defineConfig, type Plugin } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import path from 'path'
|
|
import { visualizer } from 'rollup-plugin-visualizer'
|
|
|
|
// https://vitejs.dev/config/
|
|
export default defineConfig(({ mode }) => {
|
|
const isProduction = mode === 'production'
|
|
|
|
return {
|
|
plugins: [
|
|
react(),
|
|
// Plugin pour générer des nonces CSP
|
|
{
|
|
name: 'csp-nonce',
|
|
generateBundle(_options: any, bundle: any) {
|
|
// Générer un nonce pour chaque build
|
|
const nonce = Buffer.from(Math.random().toString()).toString('base64')
|
|
|
|
// Injecter le nonce dans les scripts inline
|
|
for (const fileName in bundle) {
|
|
const chunk = bundle[fileName]
|
|
if (chunk.type === 'chunk' && chunk.code) {
|
|
chunk.code = chunk.code.replace(
|
|
/__CSP_NONCE__/g,
|
|
nonce
|
|
)
|
|
}
|
|
}
|
|
}
|
|
} as Plugin,
|
|
// Bundle analyzer for production builds
|
|
(isProduction && visualizer({
|
|
filename: 'dist/bundle-analysis.html',
|
|
open: false,
|
|
gzipSize: true,
|
|
brotliSize: true,
|
|
})) as Plugin,
|
|
].filter(Boolean),
|
|
test: {
|
|
globals: true,
|
|
environment: 'jsdom',
|
|
setupFiles: './src/setupTests.ts',
|
|
css: true,
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
'@': path.resolve(__dirname, './src'),
|
|
'@components': path.resolve(__dirname, './src/components'),
|
|
'@features': path.resolve(__dirname, './src/features'),
|
|
'@services': path.resolve(__dirname, './src/services'),
|
|
'@hooks': path.resolve(__dirname, './src/hooks'),
|
|
'@utils': path.resolve(__dirname, './src/utils'),
|
|
'@types': path.resolve(__dirname, './src/types'),
|
|
},
|
|
},
|
|
server: {
|
|
port: 5173,
|
|
host: true,
|
|
headers: {
|
|
'Content-Security-Policy': (() => {
|
|
const basePolicy = [
|
|
"default-src 'self'",
|
|
"worker-src 'self' blob:",
|
|
"img-src 'self' data: https: blob:",
|
|
"connect-src 'self' ws: wss: http: https:",
|
|
"font-src 'self' data:",
|
|
"object-src 'none'",
|
|
"base-uri 'self'",
|
|
"form-action 'self'",
|
|
"frame-ancestors 'none'",
|
|
"upgrade-insecure-requests"
|
|
];
|
|
|
|
// Production: Remove unsafe-inline and unsafe-eval, use nonces
|
|
// Dev: Keep unsafe-inline for Vite HMR, but remove unsafe-eval
|
|
if (isProduction) {
|
|
basePolicy.push(
|
|
"script-src 'self' 'nonce-__CSP_NONCE__' blob:",
|
|
"style-src 'self' 'nonce-__CSP_NONCE__'"
|
|
);
|
|
} else {
|
|
basePolicy.push(
|
|
"script-src 'self' 'unsafe-inline' blob:",
|
|
"style-src 'self' 'unsafe-inline'"
|
|
);
|
|
}
|
|
|
|
return basePolicy.join('; ');
|
|
})()
|
|
}
|
|
},
|
|
build: {
|
|
outDir: 'dist',
|
|
sourcemap: isProduction,
|
|
target: 'esnext',
|
|
minify: 'esbuild',
|
|
rollupOptions: {
|
|
output: {
|
|
// Manual chunk splitting removed to avoid path resolution errors
|
|
// manualChunks: { ... },
|
|
chunkFileNames: (chunkInfo) => {
|
|
const facadeModuleId = chunkInfo.facadeModuleId
|
|
? chunkInfo.facadeModuleId.split('/').pop()?.replace('.tsx', '').replace('.ts', '')
|
|
: 'chunk';
|
|
return `js/${facadeModuleId}-[hash].js`;
|
|
},
|
|
entryFileNames: 'js/[name]-[hash].js',
|
|
assetFileNames: (assetInfo) => {
|
|
const extType = assetInfo.name?.split('.').pop();
|
|
if (/png|jpe?g|svg|gif|tiff|bmp|ico/i.test(extType || '')) {
|
|
return 'images/[name]-[hash][extname]';
|
|
}
|
|
if (/woff2?|eot|ttf|otf/i.test(extType || '')) {
|
|
return 'fonts/[name]-[hash][extname]';
|
|
}
|
|
return 'assets/[name]-[hash][extname]';
|
|
},
|
|
},
|
|
},
|
|
chunkSizeWarningLimit: 1000,
|
|
},
|
|
optimizeDeps: {
|
|
include: [
|
|
'react',
|
|
'react-dom',
|
|
'zustand',
|
|
'date-fns',
|
|
'zod',
|
|
'dompurify',
|
|
'@tanstack/react-virtual',
|
|
],
|
|
exclude: ['@vite/client', '@vite/env'],
|
|
},
|
|
css: {
|
|
devSourcemap: !isProduction,
|
|
},
|
|
define: {
|
|
__CSP_NONCE__: JSON.stringify('__CSP_NONCE__')
|
|
}
|
|
}
|
|
}) |