refactor(@angular/build): lazily evaluate sideEffects in javascript transformer - #34059
Open
clydin wants to merge 1 commit into
Open
refactor(@angular/build): lazily evaluate sideEffects in javascript transformer#34059clydin wants to merge 1 commit into
clydin wants to merge 1 commit into
Conversation
clydin
force-pushed
the
perf/lazy-side-effects
branch
from
September 9, 2026 18:31
9e0d2db to
5598ecb
Compare
…ransformer Previously, compiler-plugin.ts eagerly resolved sideEffects for every JavaScript file loaded during bundling by calling await hasSideEffects(request), which executes esbuild's asynchronous build.resolve to inspect package.json. Within the JavaScript transformer, sideEffects is only needed in two specific locations: when checking if a file belongs to node_modules/@angular/ to apply top-level pure function annotations, and when determining whether to wrap decorators in side-effect-free files that lack primary candidate tokens. The sideEffects check is now evaluated lazily. Method signatures on transformData and transformFile have been simplified to accept a TransformOptions interface with an optional async sideEffects resolver callback. Inside hasAdvancedOptimizationCandidates, the resolver is only evaluated if the file matches the node_modules/@angular/ path pattern or contains decorator tokens without primary optimization tokens. If the candidate check does not query sideEffects, the resolver is never invoked, eliminating unnecessary build.resolve calls for bypassed files, linker-only modules, and files matching primary optimization tokens.
clydin
force-pushed
the
perf/lazy-side-effects
branch
from
September 9, 2026 18:46
5598ecb to
0c7035a
Compare
clydin
marked this pull request as ready for review
September 9, 2026 18:52
There was a problem hiding this comment.
Code Review
This pull request refactors the JavaScriptTransformer to accept a lazy sideEffects resolver callback instead of a pre-evaluated boolean. It introduces a new TransformOptions interface to group transformation parameters, moves caching logic from transformFile to transformData to ensure both paths benefit from caching, and updates the compiler plugin and tests accordingly. There are no review comments, so no feedback is provided.
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.
Previously,
compiler-plugin.tseagerly resolved sideEffects for every JavaScript file loaded during bundling by callingawait hasSideEffects(request), which executes esbuild's asynchronousbuild.resolveto inspectpackage.json.Within the JavaScript transformer,
sideEffectsis only needed in two specific locations: when checking if a file belongs tonode_modules/@angular/to apply top-level pure function annotations, and when determining whether to wrap decorators in side-effect-free files that lack primary candidate tokens.The
sideEffectscheck is now evaluated lazily. Method signatures on transformData and transformFile have been simplified to accept a TransformOptions interface with an optional asyncsideEffectsresolver callback. InsidehasAdvancedOptimizationCandidates, the resolver is only evaluated if the file matches thenode_modules/@angular/path pattern or contains decorator tokens without primary optimization tokens. If the candidate check does not querysideEffects, the resolver is never invoked, eliminating unnecessarybuild.resolvecalls for bypassed files, linker-only modules, and files matching primary optimization tokens.