S264 Handoff

Documentation for Sessions

S264: Technical Handoff — Platform Preview Compilation Overhaul

Session: 264.1 Date: 2026-03-24 Branch: session-261-266

Summary

Fixed critical "Failed to load Angular compiler from CDN" error in Live Preview. Root cause: esm.sh CDN singleton isolation — Angular packages bundled separate @angular/core instances, breaking JIT compiler registration. Solution: self-hosted Angular ESM runtime with shared singletons + future-proof AOT compilation architecture.

Architecture Changes

Self-Hosted Angular Runtime (Phase 1 — ACTIVE)

BEFORE: Preview iframe → import("https://esm.sh/@angular/core@20") → CDN re-bundles → duplicate singletons → BROKEN
AFTER:  Preview iframe → import("http://localhost:6200/angular-runtime/core.mjs") → shared singleton → WORKS

Build: tools/scripts/build/bundle-angular-runtime.ts

Runtime flow:

  1. BundlerService.compile() calls buildPreviewExternalsMap(window.location.origin) → absolute URLs
  2. rspack externalizes Angular packages to http://localhost:6200/angular-runtime/*.mjs
  3. PreviewServerService.updateAssets() rewrites remaining bare specifiers to absolute URLs
  4. Prerequisites script loads zone.js + compiler + PBD from /angular-runtime/ before main.js parse
  5. Blob URL iframe resolves all imports to shared /angular-runtime/ modules

Compilation Strategy (Phase 2 — CODE READY, NOT WIRED)

Interface: libs/libs-structural/platform-preview/src/lib/strategies/compilation-strategy.ts

CompilationStrategy {
  mode: 'jit' | 'aot'
  getMainTsInjection(): MainTsInjection
  getPrerequisites(runtimeBase): PrerequisiteModules
  getExternals(origin): Record<string, string>
  transformSources(files): SourceTransformResult
}

Implementations: JitCompilationStrategy (current) + AotCompilationStrategy (uses Phase 3 compiler)

Lightweight Template Compiler (Phase 3 — CODE READY, NOT WIRED)

Template HTML → TemplateParser → TemplateAST → IvyCodegen → Ivy Instructions

Bugs Fixed

  1. CDN singleton isolation — Self-hosted Angular runtime (Phase 1)
  2. NG0201 _DomRendererFactory2 — Removed provideAnimations() (FESM flat bundle duplicates)
  3. NG0200 Circular dependency for RendererFactory2 — Same root cause as #2
  4. NG0304 unknown ggs element — NO_ERRORS_SCHEMA injected into all @Component decorators
  5. NG0303 unknown property on ggs — Same fix as #4

Wiring TODO (for next session)

To activate Phase 2+3:

  1. Add CompilationStrategy as injectable in BundlerService
  2. Call strategy.getExternals() instead of buildPreviewExternalsMap() directly
  3. Call strategy.transformSources() in the enrichment pipeline
  4. Call strategy.getPrerequisites() in PreviewServerService
  5. Call strategy.getMainTsInjection() in BundlerFilesystemService.synthesizeMainTs()
  6. Add toggle in UI or config to switch between JIT/AOT
  7. Test AOT on real generated modules, verify template compiler handles all patterns

Key Conventions Established