From b72569b6b99fb9d50a63e0eed148ead9195dede5 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Mon, 16 Jun 2025 22:43:46 +0000 Subject: [PATCH] make the app buildable for prod --- crawler/frontend/.dockerignore | 4 +++ crawler/frontend/Dockerfile | 29 +++++++++++++++++++ crawler/frontend/nginx.conf | 23 +++++++++++++++ .../frontend/src/components/ui/sidebar.tsx | 13 +++++---- crawler/frontend/tsconfig.app.json | 6 ++-- crawler/frontend/tsconfig.node.json | 16 +++++----- crawler/frontend/vite.config.ts | 3 ++ 7 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 crawler/frontend/.dockerignore create mode 100644 crawler/frontend/Dockerfile create mode 100644 crawler/frontend/nginx.conf diff --git a/crawler/frontend/.dockerignore b/crawler/frontend/.dockerignore new file mode 100644 index 0000000..477ee04 --- /dev/null +++ b/crawler/frontend/.dockerignore @@ -0,0 +1,4 @@ +node_modules +.git +.env.local +*.md diff --git a/crawler/frontend/Dockerfile b/crawler/frontend/Dockerfile new file mode 100644 index 0000000..616beca --- /dev/null +++ b/crawler/frontend/Dockerfile @@ -0,0 +1,29 @@ +# Stage 1: Build the React app +FROM node:24-alpine AS builder + +WORKDIR /app + +# Copy package files first for better caching +COPY package.json package-lock.json* ./ + +# Install dependencies (prefers yarn if available) +RUN npm ci + +# Copy all files and build +COPY . . + +RUN npm run build # TODO: MOVE ME BELOW + +FROM nginx:alpine + +# Remove default nginx static files +RUN rm -rf /usr/share/nginx/html/* + +WORKDIR /app + +# Copy only necessary files from the builder stage +COPY --from=builder /app/dist /usr/share/nginx/html +COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/crawler/frontend/nginx.conf b/crawler/frontend/nginx.conf new file mode 100644 index 0000000..37035ec --- /dev/null +++ b/crawler/frontend/nginx.conf @@ -0,0 +1,23 @@ +server { + listen 80; + server_name _; + + # Root directory for static files (must match Docker COPY path) + root /usr/share/nginx/html; + index index.html; + + # Serve static files + location / { + try_files $uri $uri/ /index.html; + } + + # Enable gzip compression + gzip on; + gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; + + # Cache static assets + # location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ { + # expires 1y; + # add_header Cache-Control "public, immutable"; + # } +} diff --git a/crawler/frontend/src/components/ui/sidebar.tsx b/crawler/frontend/src/components/ui/sidebar.tsx index 5d8d3ca..508d554 100644 --- a/crawler/frontend/src/components/ui/sidebar.tsx +++ b/crawler/frontend/src/components/ui/sidebar.tsx @@ -1,10 +1,8 @@ -import * as React from "react" import { Slot } from "@radix-ui/react-slot" -import { cva, VariantProps } from "class-variance-authority" +import { cva, type VariantProps } from "class-variance-authority" import { PanelLeftIcon } from "lucide-react" +import * as React from "react" -import { useIsMobile } from "@/hooks/use-mobile" -import { cn } from "@/lib/utils" import { Button } from "@/components/ui/button" import { Input } from "@/components/ui/input" import { Separator } from "@/components/ui/separator" @@ -22,6 +20,8 @@ import { TooltipProvider, TooltipTrigger, } from "@/components/ui/tooltip" +import { useIsMobile } from "@/hooks/use-mobile" +import { cn } from "@/lib/utils" const SIDEBAR_COOKIE_NAME = "sidebar_state" const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7 @@ -567,7 +567,7 @@ function SidebarMenuAction({ "peer-data-[size=lg]/menu-button:top-2.5", "group-data-[collapsible=icon]:hidden", showOnHover && - "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0", + "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0", className )} {...props} @@ -720,5 +720,6 @@ export { SidebarRail, SidebarSeparator, SidebarTrigger, - useSidebar, + useSidebar } + diff --git a/crawler/frontend/tsconfig.app.json b/crawler/frontend/tsconfig.app.json index 0e7a068..74704af 100644 --- a/crawler/frontend/tsconfig.app.json +++ b/crawler/frontend/tsconfig.app.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + // "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "lib": [ @@ -21,9 +21,9 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": true, + // "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true, + // "noUncheckedSideEffectImports": true, "baseUrl": ".", "paths": { "@/*": [ diff --git a/crawler/frontend/tsconfig.node.json b/crawler/frontend/tsconfig.node.json index 9728af2..3cf7e83 100644 --- a/crawler/frontend/tsconfig.node.json +++ b/crawler/frontend/tsconfig.node.json @@ -1,25 +1,27 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + // "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", - "lib": ["ES2023"], + "lib": [ + "ES2023" + ], "module": "ESNext", "skipLibCheck": true, - /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, - /* Linting */ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "erasableSyntaxOnly": true, + // "erasableSyntaxOnly": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + // "noUncheckedSideEffectImports": true }, - "include": ["vite.config.ts"] + "include": [ + "vite.config.ts" + ] } diff --git a/crawler/frontend/vite.config.ts b/crawler/frontend/vite.config.ts index 3334620..4e658f6 100644 --- a/crawler/frontend/vite.config.ts +++ b/crawler/frontend/vite.config.ts @@ -7,6 +7,9 @@ import { defineConfig } from 'vite'; // https://vite.dev/config/ export default defineConfig({ plugins: [react(), tailwindcss()], + build: { + outDir: "dist" + }, resolve: { alias: { "@": path.resolve(__dirname, "./src"),