Please provide the environment you discovered this bug in.
@analogjs/vite-plugin-angular: 2.5.1 (still present on beta, 2.6.1-beta.2)
@analogjs/vitest-angular: 2.5.1
vite: 8.x (rolldown — vite.rolldownVersion is set)
vitest / @vitest/browser: 4.x
node: 24
OS: macOS (not OS specific)
Which area/package is the issue in?
vite-plugin-angular
Description
On Vite 8 (rolldown), createDepOptimizerConfig adds a compiler plugin to the dep optimizer in two flavors:
- the esbuild one (
createCompilerPlugin) gets an isTest flag and skips its onLoad transform in test mode. It also closes its JavaScriptTransformer in onEnd.
- the rolldown one (
createRolldownCompilerPlugin) gets neither. It always transforms, and never closes.
So when running vitest on Vite 8, every prebundled .js/.cjs/.mjs dependency is piped through Angular's JavaScriptTransformer (the Babel linker from @angular/build/private), built with one worker and never shut down.
With a large package in optimizeDeps.include, the optimizer can stall before the vitest RUN banner even shows. The same package prebundles in seconds in a plain Vite config without the plugin. Leaving the package out of optimizeDeps.include is the only workaround.
Code:
packages/vite-plugin-angular/src/lib/compiler-plugin.ts — the esbuild variant has if (!isTest) and build.onEnd(() => javascriptTransformer.close()); the rolldown variant has neither.
packages/vite-plugin-angular/src/lib/utils/plugin-config.ts — createRolldownCompilerPlugin is called without opts.isTest / close flag, while createCompilerPlugin right below gets both.
Please provide the exception or error you saw
No exception. The dep optimizer stalls (or runs slowly) before the vitest RUN banner
when a large JS-heavy package is in optimizeDeps.include on Vite 8 + rolldown.
Other information
Suggested fix: mirror the esbuild variant — skip the load transform when isTest, and close the transformer in buildEnd. JavaScriptTransformer.close() resets its lazy worker pool, so a later optimizer run just creates it again. I have a fix with tests ready and will open a PR.
I would be willing to submit a PR to fix this issue
Yes
Please provide the environment you discovered this bug in.
Which area/package is the issue in?
vite-plugin-angular
Description
On Vite 8 (rolldown),
createDepOptimizerConfigadds a compiler plugin to the dep optimizer in two flavors:createCompilerPlugin) gets anisTestflag and skips itsonLoadtransform in test mode. It also closes itsJavaScriptTransformerinonEnd.createRolldownCompilerPlugin) gets neither. It always transforms, and never closes.So when running vitest on Vite 8, every prebundled
.js/.cjs/.mjsdependency is piped through Angular'sJavaScriptTransformer(the Babel linker from@angular/build/private), built with one worker and never shut down.With a large package in
optimizeDeps.include, the optimizer can stall before the vitest RUN banner even shows. The same package prebundles in seconds in a plain Vite config without the plugin. Leaving the package out ofoptimizeDeps.includeis the only workaround.Code:
packages/vite-plugin-angular/src/lib/compiler-plugin.ts— the esbuild variant hasif (!isTest)andbuild.onEnd(() => javascriptTransformer.close()); the rolldown variant has neither.packages/vite-plugin-angular/src/lib/utils/plugin-config.ts—createRolldownCompilerPluginis called withoutopts.isTest/ close flag, whilecreateCompilerPluginright below gets both.Please provide the exception or error you saw
Other information
Suggested fix: mirror the esbuild variant — skip the
loadtransform whenisTest, and close the transformer inbuildEnd.JavaScriptTransformer.close()resets its lazy worker pool, so a later optimizer run just creates it again. I have a fix with tests ready and will open a PR.I would be willing to submit a PR to fix this issue
Yes