fix(@angular-devkit/build-angular): do not mark standalone expression statements as pure - #34206
Merged
clydin merged 1 commit intoSep 30, 2026
Merged
Conversation
… 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
There was a problem hiding this comment.
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.
alan-agius4
approved these changes
Sep 30, 2026
Member
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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