From e6e3bc39d4aa1b8bc417d6a0b0dc11b8e383c184 Mon Sep 17 00:00:00 2001 From: dwindown Date: Fri, 2 Jan 2026 11:21:39 +0700 Subject: [PATCH] Fix production build error with proper vendor chunk splitting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Configure Vite to split vendor chunks (React, DOMPurify, video libs, Supabase) - Add manual chunk configuration to prevent duplicate module bundling - Clean Docker build cache and node_modules cache during build - Update Dockerfile to force clean rebuilds This should resolve the 'Identifier already declared' error in production caused by DOMPurify's @xmldom dependency being bundled multiple times. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 --- Dockerfile | 8 ++++---- vite.config.ts | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2b74305..5f581f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,14 +7,14 @@ WORKDIR /app # Copy package files COPY package*.json ./ -# Install dependencies -RUN npm ci +# Install dependencies with clean install +RUN npm ci --prefer-offline --no-audit --force # Copy source code COPY . . -# Build the application -RUN npm run build +# Clean any previous build artifacts and node_modules cache, then build +RUN rm -rf dist node_modules/.cache && npm run build # Production stage - Use a simple server that works with Coolify FROM node:18-alpine AS production diff --git a/vite.config.ts b/vite.config.ts index fa5b6af..5852118 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -18,5 +18,33 @@ export default defineConfig(({ mode }) => ({ build: { // Disable minification completely to avoid variable conflicts minify: false, + // Prevent duplicate bundling of dependencies + rollupOptions: { + output: { + manualChunks: (id) => { + // Vendor chunks for better caching and deduplication + if (id.includes('node_modules')) { + // Group DOMPurify and its dependencies separately + if (id.includes('dompurify') || id.includes('@xmldom')) { + return 'vendor-dompurify'; + } + // Group React separately + if (id.includes('react') || id.includes('react-dom') || id.includes('react-router')) { + return 'vendor-react'; + } + // Group video libraries + if (id.includes('video.js') || id.includes('hls.js') || id.includes('plyr')) { + return 'vendor-video'; + } + // Group Supabase + if (id.includes('@supabase')) { + return 'vendor-supabase'; + } + // All other node_modules + return 'vendor'; + } + }, + }, + }, }, }));