diff --git a/Frontend/erp-system/.dockerignore b/Frontend/erp-system/.dockerignore index de22555..78ff4b9 100644 --- a/Frontend/erp-system/.dockerignore +++ b/Frontend/erp-system/.dockerignore @@ -2,6 +2,7 @@ node_modules .next out build +dist coverage .vercel diff --git a/Frontend/erp-system/.gitignore b/Frontend/erp-system/.gitignore index 2b411dd..306c87b 100644 --- a/Frontend/erp-system/.gitignore +++ b/Frontend/erp-system/.gitignore @@ -19,6 +19,7 @@ # production /build +/dist # misc .DS_Store diff --git a/Frontend/erp-system/build.ps1 b/Frontend/erp-system/build.ps1 new file mode 100644 index 0000000..6088377 --- /dev/null +++ b/Frontend/erp-system/build.ps1 @@ -0,0 +1,106 @@ +<# +.SYNOPSIS + Builds the ERP frontend (Next.js) and packages it into a deployable zip. + +.DESCRIPTION + 1. Installs dependencies (npm ci) when node_modules is missing or -CleanInstall is set + 2. Runs `npm run build` + 3. Copies the runtime files into dist/ and zips them + + The /api/* rewrite to the backend is resolved at BUILD time (next.config.ts -> + routes-manifest.json), so BACKEND_ORIGIN must be correct for the target environment + when you build, not when you start the server. + +.PARAMETER BackendOrigin + Origin of the ERPCore backend, e.g. http://127.0.0.1:6701. Overrides BACKEND_ORIGIN + from the environment / .env.local for this build only. + +.PARAMETER CleanInstall + Delete node_modules and reinstall from package-lock.json. + +.PARAMETER NoZip + Build and stage the files in dist/erp-frontend but do not create the zip. + +.EXAMPLE + .\build.ps1 -BackendOrigin http://127.0.0.1:6701 +#> +[CmdletBinding()] +param( + [string]$BackendOrigin, + [switch]$CleanInstall, + [switch]$NoZip +) + +$ErrorActionPreference = "Stop" +Set-Location $PSScriptRoot + +function Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan } + +function Invoke-Npm { + & npm @args + if ($LASTEXITCODE -ne 0) { throw "npm $($args -join ' ') failed (exit $LASTEXITCODE)" } +} + +if (-not (Get-Command node -ErrorAction SilentlyContinue)) { throw "Node.js is not installed or not on PATH." } +if (-not (Get-Command npm -ErrorAction SilentlyContinue)) { throw "npm is not installed or not on PATH." } + +$env:NEXT_TELEMETRY_DISABLED = "1" +if ($BackendOrigin) { $env:BACKEND_ORIGIN = $BackendOrigin } + +# --- Install ----------------------------------------------------------------- +if ($CleanInstall -and (Test-Path node_modules)) { + Step "Removing node_modules" + Remove-Item node_modules -Recurse -Force +} +if (-not (Test-Path node_modules)) { + Step "Installing dependencies (npm ci)" + Invoke-Npm ci +} +else { + Write-Host "node_modules found, skipping install (use -CleanInstall to reinstall)." -ForegroundColor DarkGray +} + +# --- Build ------------------------------------------------------------------- +$origin = if ($env:BACKEND_ORIGIN) { $env:BACKEND_ORIGIN } else { "(from .env.local, else http://127.0.0.1:6701)" } +Step "Building (BACKEND_ORIGIN = $origin)" +Invoke-Npm run build + +# --- Package ----------------------------------------------------------------- +Step "Packaging" +$dist = Join-Path $PSScriptRoot "dist" +$stage = Join-Path $dist "erp-frontend" +if (Test-Path $stage) { Remove-Item $stage -Recurse -Force } +New-Item -ItemType Directory -Force $stage | Out-Null + +# .next without the build cache and dev output (hundreds of MB, not needed at runtime) +& robocopy ".next" (Join-Path $stage ".next") /E /NFL /NDL /NJH /NJS /NP /XD cache dev diagnostics | Out-Null +if ($LASTEXITCODE -ge 8) { throw "robocopy .next failed (exit $LASTEXITCODE)" } + +& robocopy "public" (Join-Path $stage "public") /E /NFL /NDL /NJH /NJS /NP | Out-Null +if ($LASTEXITCODE -ge 8) { throw "robocopy public failed (exit $LASTEXITCODE)" } + +foreach ($f in "package.json", "package-lock.json", "next.config.ts") { + Copy-Item $f $stage +} + +if ($NoZip) { + Write-Host "`nStaged at: $stage" -ForegroundColor Green + exit 0 +} + +$stamp = Get-Date -Format "yyyyMMdd-HHmmss" +$zip = Join-Path $dist "erp-frontend-$stamp.zip" +# bsdtar (built into Windows 10+) writes forward-slash entry names. Windows PowerShell 5.1's +# ZipFile/Compress-Archive write backslashes, which unzip on Linux as literal "a\b" filenames. +& tar.exe -a -c -f $zip -C $stage . +if ($LASTEXITCODE -ne 0) { throw "tar failed (exit $LASTEXITCODE)" } + +$sizeMb = [math]::Round((Get-Item $zip).Length / 1MB, 1) +Write-Host "`nBuild OK: $zip ($sizeMb MB)" -ForegroundColor Green +Write-Host @" + +To run on the server: + unzip, then in the folder: + npm ci --omit=dev + PORT=6702 npm start +"@