Skip to content

fix(vite): define ngServerMode per environment - #685

Merged
Brooooooklyn merged 2 commits into
voidzero-dev:mainfrom
benjavicente:fix/ng-server-mode-per-environment
Nov 9, 2026
Merged

Brooooooklyn merged 2 commits into
voidzero-dev:mainfrom
benjavicente:fix/ng-server-mode-per-environment

Conversation

@benjavicente

@benjavicente benjavicente commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Made by agents
🙋‍♂️ Human review: This matches what I see on Vite's guide on setting up the environment and a migration guide for the environment hooks.

Fixes #684

Summary: the build optimizer set ngServerMode once, from the top-level build.ssr, in the define / oxc.define every environment shares. In Environment API builds (vite build --app, builder.buildApp), the server environment got false, so Angular bundled into it kept a process-wide platform injector and concurrent SSR requests failed with NG0404. This PR defines it per environment, like the Angular CLI.

Changes

  • angular-build-optimizer-plugin.ts: ngServerMode moves from the config hook to configEnvironment. Server environments get true (this includes vite build --ssr), a production client gets false, and a non-production client still gets nothing. It is no longer in the shared oxc.define.
  • angular-ssr-manifest-plugin.ts: same per-run detection; it now checks the environment's consumer, so the manifests are also injected in Environment API builds. It does nothing outside Vite (plain rolldown / tsdown give no this.environment), and skips code that already sets the manifest, since a server environment can bundle another one's output (Nitro).

Tests

  • build-optimizer.test.ts: resolves real Vite build configs: client + server environments from one config, build.ssr, development mode, and the shared defines. Three of the four fail without this change; the build.ssr one guards the existing behaviour.
  • ssr-manifest.test.ts: the manifests are injected in a server environment and not in a client one.
  • ssr-manifest.test.ts: no second injection, and no error without an environment.
  • End to end: the reproduction below gets ngServerMode: true in the server bundle, and a TanStack Start app built with this change answers 12 concurrent requests with 12 × 200 (only some succeeded before, the rest failed with NG0404).

Reproduction: https://github.com/benjavicente/oxc-angular-repro-ng-server-mode

benjavicente and others added 2 commits November 8, 2026 22:22
The build optimizer set `ngServerMode` once, from the top-level
`build.ssr`, in the `define` and `oxc.define` every environment shares.
With the Environment API (`vite build --app`, `builder.buildApp`), one
config builds the client and the server, `build.ssr` is not set at the
top level, and the server environment got `ngServerMode = false`. Angular
bundled into it then kept a process-wide platform injector and ran
`afterRender` hooks on the server, so concurrent requests failed with
NG0404.

Define `ngServerMode` in `configEnvironment` instead: `true` for server
environments (which includes `vite build --ssr`), and `false` for a
production client environment, like the Angular CLI. The SSR manifest
plugin had the same per-run detection and never injected the manifests in
these builds; it now checks the environment's `consumer`.
…eated

- `this.environment` is only set by Vite. Under plain rolldown / tsdown
  (library builds) `buildStart` threw "Cannot read properties of
  undefined (reading 'config')"; before, the plugin did nothing there.
- Every server environment now injects the manifests, so one that
  bundles another's output (Nitro builds the `ssr` service, then bundles
  it) injected them twice, with a second copy of the app. Skip code that
  already calls `ɵsetAngularAppManifest`.
- The development-mode `ngServerMode` test stubs `NODE_ENV`, which the
  plugin also reads, so it passes under `NODE_ENV=production`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Brooooooklyn

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-09T08:51:32.513922Z 01cde40 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🎉

Reviewed commit: 01cde40354

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Brooooooklyn
Brooooooklyn merged commit 4d09d3c into voidzero-dev:main Nov 9, 2026
9 checks passed
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.

ngServerMode is defined as false in the server environment of Environment API builds

2 participants