You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactors the InnerGraph tree-shaking utility so purity can be tracked across module boundaries, not just
within a single module.
What kind of change does this PR introduce?
TL;DR
A /*#__NO_SIDE_EFFECTS__*/ annotation in one module is now honored by call sites in other modules — not
just within the file it was declared in.
Example
// pure.js/*#__NO_SIDE_EFFECTS__*/exportfunctionpureFn(x){returnx;}// index.jsimport{pureFn}from"./pure";constr=pureFn(1);// result never read
Before this PR, pureFn shows up in usedExports because the /*#__NO_SIDE_EFFECTS__*/ hint stayed inside pure.js and never reached the importer, so the call site pureFn(1) was treated as a usage with sideEffects.
After this PR, pureFn export can be tree-shaken.
How the optimization works:
Producer records purity locally. While parsing pure.js, the parser sees the /*#__NO_SIDE_EFFECTS__*/ and writes the name into module.buildInfo.pureFunctions. At this point the purity is just a per-module fact.
Purity is lifted onto the export descriptor. When HarmonyExportSpecifierDependency / HarmonyExportExpressionDependency build their ExportsSpec, they consult buildInfo.pureFunctions and emit { name: "pureFn", isPure: true }. This is the
only channel that crosses the module boundary.
FlagDependencyExportsPlugin propagates isPure to ExportInfo and the
new isPure flag is copied onto the matching ExportInfo.
Importer tags the local binding with a deferred pure predicate. When index.js is parsed, the inner graph
creates a TopLevelSymbol for the imported pureFn and its pure field is a function for purpose of deferring instead of definite true. The deferral matters because the importing module may not yet be parsed.
Per-compilation state. Inner-graph state is now scoped to the Compilation
(getInnerGraph(compilation)) and keyed by Module, which is what lets step 4 reach into another module's ExportsInfo from inside the importer's graph.
Inference resolves the call. When inferDependencyUsage walks the importer's graph, it reaches the pureFn(1) call, asks the symbol isPure(compilation, module), gets true, so propagate pure-symbol usage through the inner graph.
Did you add tests for your changes?
Yes
Does this PR introduce a breaking change?
No
If relevant, what needs to be documented once your changes are merged or what have you already documented?
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
❌ Patch coverage is 17.85714% with 299 lines in your changes missing coverage. Please review.
✅ Project coverage is 36.35%. Comparing base (3032402) to head (b53d0c6).
❌ Your patch check has failed because the patch coverage (17.85%) is below the target coverage (90.00%). You can increase the patch coverage or adjust the target coverage.
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
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.
Summary
Refactors the InnerGraph tree-shaking utility so purity can be tracked across module boundaries, not just
within a single module.
What kind of change does this PR introduce?
TL;DR
A
/*#__NO_SIDE_EFFECTS__*/annotation in one module is now honored by call sites in other modules — notjust within the file it was declared in.
Example
Before this PR,
pureFnshows up inusedExportsbecause the/*#__NO_SIDE_EFFECTS__*/hint stayed insidepure.jsand never reached the importer, so the call sitepureFn(1)was treated as a usage withsideEffects.After this PR,
pureFnexport can be tree-shaken.How the optimization works:
Producer records purity locally. While parsing
pure.js, the parser sees the/*#__NO_SIDE_EFFECTS__*/and writes the name intomodule.buildInfo.pureFunctions. At this point the purity is just a per-module fact.Purity is lifted onto the export descriptor. When
HarmonyExportSpecifierDependency / HarmonyExportExpressionDependencybuild theirExportsSpec, they consultbuildInfo.pureFunctionsand emit{ name: "pureFn", isPure: true }. This is theonly channel that crosses the module boundary.
FlagDependencyExportsPluginpropagatesisPureto ExportInfo and thenew
isPureflag is copied onto the matchingExportInfo.Importer tags the local binding with a deferred pure predicate. When
index.jsis parsed, the inner graphcreates a
TopLevelSymbolfor the importedpureFnand itspurefield is a function for purpose ofdeferringinstead of definitetrue. The deferral matters because the importing module may not yet be parsed.Per-compilation state.
Inner-graphstate is now scoped to the Compilation(
getInnerGraph(compilation)) and keyed byModule, which is what lets step 4 reach into another module'sExportsInfofrom inside the importer's graph.Inference resolves the call. When
inferDependencyUsagewalks the importer's graph, it reaches thepureFn(1)call, asks the symbolisPure(compilation, module), gets true, so propagate pure-symbol usage through the inner graph.Did you add tests for your changes?
Yes
Does this PR introduce a breaking change?
No
If relevant, what needs to be documented once your changes are merged or what have you already documented?
No
Use of AI
Partial