Skip to content

Compiler roots and lifecycle handoffs fail across Angular compilation modes and Vite versions #2518

Closed as not planned

Description

@benpsnyder

Please provide the environment you discovered this bug in.

git clone --branch fix/compiler-vite-compat https://github.com/benpsnyder/analog.git analog-compiler-repro
cd analog-compiler-repro
git checkout 5277af9f7547e95cc4cebaec9cb05085a23e8647
pnpm install --frozen-lockfile --ignore-scripts
NX_DAEMON=false NX_NO_CLOUD=true pnpm exec nx test vite-plugin-angular --testFiles=src/lib/compiler-roots.spec.ts --watch=false --skipNxCache

Use Node 24.15.0 for these commands. --ignore-scripts avoids the workspace-wide prepare build; the focused test builds its own temporary library. No hosted application or credentials are required.

Which area/package is the issue in?

vite-plugin-angular, with the shared package declaration emitter as supporting build infrastructure.

Description

This is the dedicated compiler workstream requested in Brandon's review of analogjs/analog#2516. It separates compiler behavior and compatibility from the workspace/Vitest upgrade, platform SSR, server-function transport, Query lifetimes, and streaming work.

The smallest consumer example is a Vite library that replaces a component file with one outside the original TypeScript roots:

angular({
  tsconfig: 'tsconfig.json',
  jit: false,
  fileReplacements: [
    { replace: 'src/original.ts', with: 'src/replacement.ts' },
  ],
});

When tsconfig.json includes only the original configured entry, the replacement must still be part of Angular's program. The real-build regression instead receives JavaScript with __decorate and the original Component decorator, without defineComponent: compilation fell through to a generic TypeScript transform. The experimental Compilation API also loses integration-provided roots.

The focused tests expose related handoff failures:

Trigger Observed behavior Expected behavior
A third source of compiler roots is passed to union Replacement or integration files are dropped because union accepts two arrays Preserve and deduplicate every configured source of roots
Production dependency optimization on the Rolldown path Lifecycle ownership occupies the isTest argument, disabling transformation Treat test mode and transformer ownership separately
Transform arrives before initial compilation settles Transform returns undefined instead of emitted Angular output Wait for the in-flight compilation
Experimental HMR updates a Vite 8 mixed module Writing the getter-only isSelfAccepting property throws Update the client environment's module
Library compilation enables declarations inside Angular's Compilation API Invalid inline-source options or declaration text replacing JavaScript output Retain usable JavaScript; run library declaration generation separately
Plugin setup or stylesheet processing throws The contextual error loses its original cause Preserve cause identity along with plugin/file context
A type-only source changes between package builds The existing declaration is retained with the old interface member Refresh declarations on every build

Additional focused tests can be selected with:

NX_DAEMON=false NX_NO_CLOUD=true pnpm exec nx test vite-plugin-angular --testFiles=src/lib/compilation-api/compilation-api-plugin.spec.ts,src/lib/analog-plugin-interop.spec.ts,src/lib/oxc-dts-plugin.spec.ts --watch=false --skipNxCache

Please provide the exception or error you saw

TypeError: Cannot set property isSelfAccepting of #<Object> which has only a getter
AssertionError: expected undefined to match object { code: 'export const value = 1;' }
AssertionError: expected declaration output containing 'first?: boolean' to contain 'second?: string'
TS5051: Option 'inlineSources' can only be used when either '--inlineSourceMap' or '--sourceMap' is provided.

Other information

Implementation is published in analogjs/analog#2520, targeting alpha. Current head e767273de6e3b8589b39c815ccdae4db1a6b7e62 passes the compiler/conformance matrix, nine installed Angular/Vite consumer jobs, browser HMR, Windows, and main CI. The PR documents its tested compilation modes, examples, and shared route-policy prerequisite. The reproduction above remains pinned to the original failing implementation; this issue stays open pending merge.

Acceptance criteria for the focused PR:

  • Preserve normal compilation and explicitly test the experimental option enabled and disabled.
  • Verify test/watch behavior and externally owned Astro transformer cleanup.
  • Exercise actual installed packages with Vite 6, 7, and 8 and supported Angular versions, alongside compiler conformance/API tests.
  • Verify normal and fast full/partial compilation, compiler roots, emitted JavaScript, and repeated declaration builds.
  • Make unavailable experimental APIs fail during configuration with an actionable diagnostic; do not infer availability from the Angular version alone.
  • Include the reproduction, package typecheck/build/lint tests, compatibility CI, and concise documentation in this PR.

The workspace/Vitest 5 migration continues separately in analogjs/analog#2508. The environment and failure evidence above describe the pinned baseline; current compatibility results are recorded in the linked compiler PR.

I would be willing to submit a PR to fix this issue

  • Yes

Prepared with OpenAI Codex; findings were checked against local source and executable regressions.

Activity

  1. added a commit that references this issue on Sep 7, 2026
    47ca5f2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions