Repository navigation
Conversation
… pure The build optimizer annotated top-level calls `/* @__PURE__ */` in every `fesm20*` file, so production builds tree-shook side-effect-only calls: zone.js bundled to nothing and `@angular/compiler` lost `publishFacade`. Like the Angular CLI, only mark top-level calls pure in `@angular/*` packages whose nearest `package.json` declares the file side-effect-free. `sideEffects` arrays are matched as Vite matches them. Metadata elision, static member wrapping and enum adjustment are unchanged. Fixes voidzero-dev#595 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Summary
Fixes #595.
In production builds,
@oxc-angular/vite-optimizerranoptimizeAngularPackage(..., { markPure: true })on everyfesm20*file and ignored the package'ssideEffects. Top-level calls that exist only for their side effects got/* @__PURE__ */and were tree-shaken:zone.js(nosideEffectsfield) bundled to nothing, so a zone-based app failed withNG0908at bootstrap.@angular/compiler("sideEffects": ["./fesm2022/compiler.mjs"]) lostpublishFacade(_global), so JIT failed withJIT compiler unavailable.What changed
The optimizer plugin now passes
markPure: trueonly for files undernode_modules/@angular/whose nearestpackage.jsonmarks them side-effect-free. Everything else getsmarkPure: false. Metadata elision, static member wrapping and enum adjustment run as before.sideEffectsis read from the nearestpackage.json, cached per directory, and matched the way Vite's resolver matches it: a boolean as is,[]as side-effect-free, and array patterns throughcreateFilterrelative to the package directory, with**/prepended to patterns that have no/.this.getModuleInfo(id).moduleSideEffectscan't be used here: in a Vite 8.3.4 build it isnullin thetransformhook forzone.js,@angular/coreand@angular/compiler.How it matches the Angular CLI
In
@angular/build(22.2),javascript-transformer-worker.jscomputessafeAngularPackage = sideEffects === false && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename), and only safe packages get top-level pure annotations (topLevelSafeMode = !safeAngularPackage).sideEffectscomes from esbuild'sbuild.resolve(), which applies thepackage.jsonfield. Metadata elision, static member wrapping and enum adjustment run for every file, so they stay ungated here too.Two differences remain:
"sideEffects": false(e.g.@ngrx/store) no longer get top-level pure annotations, as in the Angular CLI. Those modules are still dropped whole when unused.newon a short list of known side-effect-free constructors. This PR doesn't port that.Verification
test/build-optimizer.test.tsdrives the plugin on fixture packages written to a temp dir. Cases: a package withoutsideEffects,sideEffects: false, an array that matches the file, an array that doesn't, a pattern with no/,[], a side-effect-free non-@angularpackage, and static member wrapping in a side-effectful package. 4 of the 8 tests fail onmain; all pass with the fix.pnpm test(455 passed),pnpm check,tsc -p tsconfig.json.vite build(Vite 8.3.4, Angular 22.2.0,zone.js0.16.0) of an app that importszone.jsand@angular/compilerand usesprovideZoneChangeDetection():@oxc-angular/vite@0.0.42, the bundle has noloadZone()/patchCommon()/publishFacade()calls, and the app throwsNG0908at bootstrap.setTimeoutin the component runs in theangularzone and updates the view, andng.ɵcompilerFacadeis set.@angular/core+@angular/platform-browseronly) builds to a byte-identical bundle with 0.0.42 and with this branch.🤖 Generated with Claude Code