Skip to content

fix(@angular-devkit/build-angular): do not mark standalone expression statements as pure - #34206

Merged
clydin merged 1 commit into
angular:mainfrom
clydin:fix/pure-toplevel-expression-statements
Sep 30, 2026
Merged

clydin merged 1 commit into
angular:mainfrom
clydin:fix/pure-toplevel-expression-statements

Conversation

@clydin

@clydin clydin commented Sep 29, 2026

Copy link
Copy Markdown
Member

Top-level call and new expressions that appear directly as expression statements are executed solely for their side effects, such as class property initialization, static blocks, and helper calls.

When targeting browsers requiring class static block or property lowering (e.g., Chrome < 94), Babel's preset-env lowers self-referencing static properties into zero-argument IIFEs (and static blocks into _staticBlock() calls). Because pure-toplevel-functions previously only skipped IIFEs if they had arguments, zero-argument IIFE statements were marked as pure. Downstream minifiers (such as esbuild) then eliminated these standalone pure statements as dead code, dropping essential class members like Injector.ɵprov and causing NG0201 at bootstrap.

This change ensures that call and new expressions that are directly expression statements are never annotated as pure, avoiding accidental elimination of side-effecting statements without requiring hardcoded whitelists of helper function names.

Fixes #34017

… statements as pure

Top-level call and new expressions that appear directly as expression
statements are executed solely for their side effects, such as class
property initialization, static blocks, and helper calls.

When targeting browsers requiring class static block or property lowering
(e.g., Chrome < 94), Babel's preset-env lowers self-referencing static
properties into zero-argument IIFEs (and static blocks into _staticBlock()
calls). Because pure-toplevel-functions previously only skipped IIFEs if
they had arguments, zero-argument IIFE statements were marked as pure.
Downstream minifiers (such as esbuild) then eliminated these standalone
pure statements as dead code, dropping essential class members like
Injector.ɵprov and causing NG0201 at bootstrap.

This change ensures that call and new expressions that are directly
expression statements are never annotated as pure, avoiding accidental
elimination of side-effecting statements without requiring hardcoded
whitelists of helper function names.

Fixes angular#34017
@clydin clydin added the target: patch This PR is targeted for the next patch release label Sep 29, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the pure-toplevel-functions Babel plugin to avoid annotating standalone expression statements as pure, preventing minifiers from incorrectly dropping them as dead code. It also adds corresponding unit tests to cover these scenarios. The review feedback recommends using optional chaining (path.parentPath?.isExpressionStatement()) in both newly added checks to prevent potential runtime TypeErrors if path.parentPath is null.

@clydin clydin added the action: review The PR is still awaiting reviews from at least one requested reviewer label Sep 29, 2026
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels Sep 30, 2026
@clydin
clydin merged commit dd68d3a into angular:main Sep 30, 2026
43 checks passed
@clydin
clydin deleted the fix/pure-toplevel-expression-statements branch September 30, 2026 14:54
@clydin

clydin commented Sep 30, 2026

Copy link
Copy Markdown
Member Author

This PR was merged into the repository. The changes were merged into the following branches:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: @angular-devkit/build-angular target: patch This PR is targeted for the next patch release

Projects

None yet

2 participants