From b9eee0e15e6752d4c8dcaf8ddbb8056fc2cedd6f Mon Sep 17 00:00:00 2001 From: r-zakarya <82443831+r-zakarya@users.noreply.github.com> Date: Sat, 11 Jul 2026 18:32:15 +0100 Subject: [PATCH] perf(build): skip redundant per-file node --check when the test gate runs The unit suite concatenates + parses every embedded app.*.js (plus argon2) in a vm, so a syntax error already fails it. Run the ~10 cold `node --check` spawns (~3-4s) only when tests are bypassed (PM_SKIP_TESTS) or absent. Cuts the pre-compile freeze from ~7s to ~4s. Co-Authored-By: Claude Opus 4.8 --- delphi-backend/assets/BuildAssets.ps1 | 60 ++++++++++++++++----------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/delphi-backend/assets/BuildAssets.ps1 b/delphi-backend/assets/BuildAssets.ps1 index 9383bbe..43b7973 100644 --- a/delphi-backend/assets/BuildAssets.ps1 +++ b/delphi-backend/assets/BuildAssets.ps1 @@ -97,32 +97,24 @@ if (-not $node) { $node = Get-Command node -ErrorAction SilentlyContinue } $jsFiles = $files | Where-Object { $_.Relative -match '\.js$' } if ($jsFiles) { if ($node) { - foreach ($jf in $jsFiles) { - Log "Syntax check: $($jf.Relative)" - # --check prints errors to stderr and returns non-zero on failure. - # Pipe $null into node so it can NEVER block waiting on stdin - # (some Windows node shims read stdin when launched from a - # non-interactive pre-build event, which would hang the build). - $out = $null | & $node.Source --check $jf.FullPath 2>&1 - if ($LASTEXITCODE -ne 0) { - Log "JS SYNTAX ERROR in $($jf.Relative):" - Log ($out | Out-String) - throw "JS syntax check failed for $($jf.Relative) - aborting asset build." - } - } - Log "JS syntax OK." + # The unit suite concatenates + parses EVERY embedded app.*.js (plus + # argon2.js) inside a vm, so a syntax error already fails it. When the + # suite runs we skip the per-file `node --check` loop — it was ~10 cold + # node process starts (~3-4s of dead build time) checking what the tests + # re-parse anyway. We only fall back to node --check when the suite is + # bypassed (PM_SKIP_TESTS) or absent. + # ponytail: assumes every embedded .js is an APP_PARTS module (or + # argon2.js). CLAUDE.md §3.1 already requires adding a new module to + # APP_PARTS + this whitelist together, so the assumption holds by process. + $haveTests = Test-Path (Join-Path $WebRoot 'js\tests') + $runTests = ($env:PM_SKIP_TESTS -ne '1') -and $haveTests - # --- Unit test gate --------------------------------------------------- - # Run the frontend regression suite (crypto round-trip, CSV import, - # sync-merge arbitration) before embedding. A broken crypto/merge - # invariant now blocks the build the same way a syntax error does, - # instead of surfacing only after a full Delphi rebuild + manual test. - # ~1.7 s, zero deps (node:test). Skipped automatically if the suite - # isn't present. Set PM_SKIP_TESTS=1 to bypass during rapid iteration. - if ($env:PM_SKIP_TESTS -eq '1') { - Log "PM_SKIP_TESTS=1 - skipping unit tests." - } elseif (Test-Path (Join-Path $WebRoot 'js\tests')) { - Log "Running frontend unit tests..." + if ($runTests) { + # --- Unit test gate (also covers JS syntax) ----------------------- + # crypto round-trip, CSV import, sync-merge arbitration, metadata. + # A broken invariant OR a syntax error blocks the build here instead + # of surfacing only after a full Delphi rebuild. Zero deps (node:test). + Log "Running frontend unit tests (also covers JS syntax)..." Push-Location $WebRoot try { $testOut = $null | & $node.Source --test 'js/tests/**/*.test.js' 2>&1 @@ -136,6 +128,24 @@ if ($jsFiles) { throw "Frontend unit tests failed - aborting asset build. (Set PM_SKIP_TESTS=1 to bypass.)" } Log "Unit tests OK." + } else { + # No test gate this run → syntax-check each file individually so a + # broken bundle can never reach assets.res. + foreach ($jf in $jsFiles) { + Log "Syntax check: $($jf.Relative)" + # --check prints errors to stderr, returns non-zero on failure. + # Pipe $null into node so it can NEVER block on stdin (some + # Windows node shims read stdin from a non-interactive pre-build + # event, which would hang the build). + $out = $null | & $node.Source --check $jf.FullPath 2>&1 + if ($LASTEXITCODE -ne 0) { + Log "JS SYNTAX ERROR in $($jf.Relative):" + Log ($out | Out-String) + throw "JS syntax check failed for $($jf.Relative) - aborting asset build." + } + } + Log "JS syntax OK." + if ($env:PM_SKIP_TESTS -eq '1') { Log "PM_SKIP_TESTS=1 - skipping unit tests." } } } else { Log "WARNING: node not found - skipping JS syntax check + unit tests. Install Node to enable them."