Update .dockerignore and .gitignore to include 'dist' directory; add build.ps1 script for frontend packaging
This commit is contained in:
@@ -2,6 +2,7 @@ node_modules
|
|||||||
.next
|
.next
|
||||||
out
|
out
|
||||||
build
|
build
|
||||||
|
dist
|
||||||
coverage
|
coverage
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
# production
|
# production
|
||||||
/build
|
/build
|
||||||
|
/dist
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|||||||
@@ -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
|
||||||
|
"@
|
||||||
Reference in New Issue
Block a user