Skip to content

feat!(build): cross-runtime pipeline with Node.js support, idempotent debug server, and CI hardening#45

Open
ofriw wants to merge 207 commits into
mainfrom
build-process
Open

feat!(build): cross-runtime pipeline with Node.js support, idempotent debug server, and CI hardening#45
ofriw wants to merge 207 commits into
mainfrom
build-process

Conversation

@ofriw

@ofriw ofriw commented Apr 25, 2026

Copy link
Copy Markdown
Collaborator

Note: This PR was generated by an AI agent. If you'd like to talk with other humans, drop by our Discord!


Summary

Closes #44.

Redesigns the build pipeline with a strict esbuild plugin stack and two-phase CSS pipeline, adds Node.js support across createBuildContext() and startDebugServer(), hardens the debug server lifecycle, fixes file-watcher reliability on Windows, and overhauls CI + test infrastructure.


Breaking Changes

Change Before After
startDebugServer return Promise<never> (never resolves) Promise<void> (resolves on shutdown)
AppConfig.cssPath Sole CSS source Vendor/prepend CSS only; app CSS via import './index.css' in JS entry
Config auto-detection Heuristic across runtimes Runtime-specific: deno.json / package.json, no cross-runtime fallback
config.debug Leaked after server stop Saved on entry, restored on exit
NoMatchError filtering String-matching in test runner Proper NoMatchError class with exit code 2

What's New

  • Node.js supportcreateBuildContext(), startDebugServer(), and all server templates now work on Node.js
  • esbuildPlugins option on compile() and startDebugServer() — custom esbuild plugins in the client bundle pipeline
  • DebugServerSession exposed via onReady callback: { server, url, stop }
  • onReady / openBrowser options on startDebugServer
  • Concurrent-call guard on startDebugServer — rejects if another instance is running
  • Idempotent Server.stop() — promise-cached, safe to call concurrently
  • Windows polling watcher — fallback when libuv fs.watch crashes (Node 24.16.0)
  • CI matrix workflow — static analysis, formatting checks, caching across all jobs
  • RuntimeAdapter patterngetRuntime() with .exit(), .getCWD(), .setupSignalHandler(), .openBrowser()
  • Injection-based test hookswithTestCWD, withTestBrowserOpenCommand, withLogCapture, injectTestTransport, injectAppendFailure

What Changed

  • Build plugin stack — strict ordering: adapter stubs → node stubs → user plugins → CSS loader → Deno loader
  • CSS pipelinebuildCombinedCSS() merges vendor CSS (cssPath) + esbuild-bundled app CSS into /index.css with composite source maps
  • File watcher — Chokidar waits for ready before attaching handlers; native watcher resolves 8.3 short names on Windows; polling watcher capped to prevent unbounded memory
  • Debug server — lifecycle rewritten with DebugServerResources, signal handler dedup, debugServerOrigin() for URL calculation
  • Browser test runnerconsole.* → structured log() from logging/log.ts; window casts made type-safe
  • Multi-runnervalidateFilteredRuntimeOutcomes() ensures matched/no-match consistency; progress tracks started (not completed) suites
  • AGENTS.md — trimmed stale sections; added runtime-specific test registration pattern
  • Docusaurus 3.10 with @docusaurus/faster (SWC/Rspack)
  • All server templates route through getRuntime() — no direct Deno.*/process.* calls
  • Playwright version centralized in base/playwright-version.ts; CI cache key hashes that file
  • Node.js pinned to 24.15.0 across CI to avoid libuv regression

What Was Removed

  • @docusaurus/remark-plugin-npm2yarn, @docusaurus/theme-mermaid, core-js-pure, marked, stale glob, memfs, all @types/d3-*
  • Docs workspace from deno.json
  • Legacy openBrowser / getCwd internal functions from debug-server
  • isBrowser(), isDeno(), isNode() replaced by getRuntime().id in ~60+ call sites
  • Silent no-ops → explicit throw in runtime adapters
  • Redundant await on synchronous exit() calls
  • Stale AGENTS.md sections (schema registration, naming conventions, common failures, CI)

Value: Unified Deno/Node.js build pipeline, production-ready file watching on Windows, reproducible CI with static analysis, structured logging for debugging, and injection-based test infrastructure that eliminates mocks.


Attached is an agent optimized description of the changes in this PR - AGENT_REVIEW.md

ofriw and others added 30 commits April 23, 2026 22:08
…tion-testing buildAssets with esbuildPlugins
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ofriw added 27 commits June 14, 2026 08:31
@ofriw ofriw changed the title feat(build): expose esbuild plugins API and CSS bundling (#44), with RuntimeAdapter parity and hardened file-watcher feat!(build): cross-runtime pipeline with Node.js support, idempotent debug server, and CI hardening Jun 23, 2026
ofriw added 2 commits June 23, 2026 13:02
…tup:hooks

First-commit auto-bootstrap was incorrectly claimed but not actually
implemented. Update .githooks/pre-commit, deno.json, and contributing.md
to clearly state that deno task setup:hooks must be run explicitly.
- Replace any with PluginBuild in BuildPluginLike.setup() signature
- Add DenoPluginModule type for denoPluginImportState cache
- Type esbuildImportState as typeof import('esbuild') instead of any
- Remove as-any casts in getClientBuildPlugins and createBuildContext
- Remove unused APP_ENTRY_POINT import from build.ts
- Remove unused log import from cli/build-assets.ts
- Fix let to const for pending in getCachedImport
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(build)!: esbuild plugins API in compile() and dev server, with multi-chunk CSS output

1 participant