fix(vite-plugin-angular): repair CSS and Angular dep resolution regressions#2326
Conversation
✅ Deploy Preview for analog-blog ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for analog-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughThe PR centralizes dependency-optimizer configuration by routing dep-optimizer settings through Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
✅ Deploy Preview for analog-app ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Investigation notes on where this came from and what it was intended to fix: The direct regression for the active
That commit created resolve: {
conditions: ['style', ...(config.resolve?.conditions ?? [])],
}So for apps using the Angular Compilation API, the The underlying
That was intended to fix A later related commit:
kept the Relevant 10-day context:
So the short version is: the problematic behavior was not newly introduced as a targeted fix in the last 10 days. A long-standing Angular Material workaround was copied into the new Compilation API plugin path on |
|
Follow-up debug finding for the The failure was specific to the The second commit reuses Validation after rebuilding/linking local Analog packages:
If a running dev server still shows the old |
|
Follow-up on the The remaining failure was not the root Tailwind stylesheet. Analog serves Angular component styles through hashed ids so Angular can load This works by keeping the public hashed ids, but resolving them back to their real source stylesheet path before Vite/Tailwind transform the CSS. The stylesheet registry now records a served source path for both external to: Tailwind then resolves Validation:
|
…css imports
The Angular Vite plugin injected the `style` package-export condition
into Vite's *global* `resolve.conditions` (in `angular-vite-plugin`,
`fast-compile-plugin`, `compilation-api-plugin`, and the shared
`createDepOptimizerConfig`). That global injection was needed so JS-side
imports of CSS files whose package exports gate them only under `style`
— e.g. `import '@angular/material/prebuilt-themes/azure-blue.css'` —
could resolve at all.
But globalising `style` had a load-bearing side effect: Tailwind v4's
`@plugin` JS resolver inherits Vite's `resolve.conditions`. With `style`
in scope, Tailwind matched the `style` export of packages with mixed
exports (notably `tailwindcss-primeui`, whose `.` exports include both
`style: "./v4/index.css"` and `import: "./v3/index.js"`) and handed the
resolved `.css` file to Node's ESM loader, which crashed with:
Internal server error: Unknown file extension ".css" for
…/tailwindcss-primeui/v4/index.css
Removing the `style` injection outright (as PR #2326 proposes) trades
one regression for another: it breaks `@angular/material/prebuilt-themes`
and any other package that exposes its CSS only under `style`.
This commit scopes the `style` condition to `.css`-extension requests
via a new `cssExtensionStyleResolverPlugin`, registered once at the
`angular()` factory level. The plugin builds its own scoped resolver
(via Vite 8's `vite.createIdResolver` or Vite 7's
`ResolvedConfig.createResolver`) with `style` appended to the user's
configured conditions, and only fires when the requested id is a bare
specifier ending in `.css` (with optional `?inline` / `?module` query).
Net effect:
- `import '@angular/material/prebuilt-themes/azure-blue.css'` ✓
- `@import '@angular/material/prebuilt-themes/azure-blue.css'` ✓
- `import '@angular/material/button'` (non-CSS) ✓
- `@plugin 'tailwindcss-primeui'` (Tailwind JS resolver) ✓
Tests:
- `cssExtensionStyleResolverPlugin` (new, 6 cases) covers the
fire/no-fire cases, condition appending, and both Vite version paths
via a `vi.mock('vite', …)`-backed resolver factory.
- `createDepOptimizerConfig` test asserts the helper no longer
returns a global `resolve` block.
11376c5 to
b199296
Compare
Summary
Fixes two Vite resolution regressions in the Angular plugin paths:
@pluginimports could resolve packagestyleexports as JavaScript modules.Both failures were reproduced from
snyder-appsusingapps/meritos/edge-gui-portalwith the local Analog packages rebuilt and linked.Root Cause
Tailwind CSS plugin resolution
A consumer stylesheet reproduced the resolver failure:
tailwindcss-primeui@0.6.1exposes separate package exports:styleresolves tov4/index.cssimportresolves tov3/index.jsAnalog injected
styleinto Vite's globalresolve.conditions, so Tailwind's JavaScript plugin resolver selected the CSS export. Node then attempted to import the CSS file as ESM and failed with:Angular Compilation API dependency linking
apps/meritos/edge-gui-portal/vite.config.mtsusesuseAngularCompilationAPI: true. That path disabled Vite's normal app transforms, but it only configured a minimaloptimizeDepsinclude/exclude list and did not install Analog's Angular dep optimizer linker plugin.As a result, Vite's dev optimizer cached Angular packages in their partially compiled declaration form. The runtime then failed when
PlatformLocationstill containedɵɵngDeclareFactory(...)and Angular tried to fall back to JIT without@angular/compilerloaded:What Changed
resolve.conditions: ['style', ...]from the Angular Vite plugin config paths.createDepOptimizerConfig()in the Angular Compilation API plugin path.tslibin the shared dep optimizer include list.styleto global resolution;rxjs/operators,rxjs, andtslib.Before / After
Before this change, the portal build failed while processing
apps/meritos/edge-gui-portal/src/app/styles/main.cssbecausetailwindcss-primeuiresolved to:After this change, the consumer Vite config resolves JS plugin imports without the
stylecondition:{ "conditions": ["module", "browser", "development|production"], "primeui": ".../tailwindcss-primeui/v3/index.js" }Before the Compilation API fix, the Vite dep cache could contain Angular partial declarations such as
ɵɵngDeclareFactoryforPlatformLocation.After this change, forced optimization produces linked Angular deps. The checked cache files for
@angular/common,@angular/common/http,@angular/platform-browser,@angular/router, and the generated platform-location chunk no longer containngDeclareFactory/ɵɵngDeclareFactory.Validation
Passed in the Analog repo:
pnpm exec vitest run \ packages/vite-plugin-angular/src/lib/angular-vite-plugin-live-reload.spec.ts \ packages/vite-plugin-angular/src/lib/angular-vite-plugin.spec.ts \ packages/vite-plugin-angular/src/lib/compilation-api/compilation-api-plugin.spec.ts \ packages/vite-plugin-angular/src/lib/utils/plugin-config.spec.ts \ --config packages/vite-plugin-angular/vite.config.tsResult:
4 files / 131 testspassed.Passed through the local Analog debug flow after rebuild/link refresh:
Passed consumer optimization/linker sanity check:
Then verified no Angular partial declaration helpers remained in the relevant optimized Angular cache files.
Passed the original consumer build:
Result:
meritos-edge-gui-portaland its 34 dependent build tasks completed successfully.Additional check:
Result: still fails on existing dependent-library Vite config type overload / excessive stack depth errors, unrelated to these Vite plugin regressions.