fix(vite): rebuild component styles when a transitive preprocessor dependency changes - #425
Open
Alexays wants to merge 1 commit into
Open
fix(vite): rebuild component styles when a transitive preprocessor dependency changes#425Alexays wants to merge 1 commit into
Alexays wants to merge 1 commit into
Conversation
…pendency changes resolveResources runs each styleUrl through Vite's preprocessCSS but discarded the deps it reports (Sass partials pulled in through @use, @import or meta.load-css, Less imports, ...). Editing such a shared partial therefore never invalidated the compiled style nor dispatched component HMR: the dev server kept serving the stale CSS until the styleUrl file itself was touched. Track the reported deps per compiled style, map each dep back to every style built on top of it, and on a hot update of a dep invalidate those styles and dispatch HMR for each owning component. A dep shared by several components (a design-system partial, typically) updates all of them, not just the last registered owner.
Brooooooklyn
reviewed
Aug 4, 2026
| "@playwright/test": "^1.58.0", | ||
| "@types/node": "catalog:", | ||
| "oxfmt": "catalog:", | ||
| "sass": "^1.93.2", |
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.
Problem
Editing a stylesheet that a component style depends on transitively (a Sass partial pulled in through
@use/@import/meta.load-css, a Less import, ...) does nothing in dev mode: the compiled component style is cached and no HMR update is dispatched. The stale CSS is served until thestyleUrlfile itself is touched (or the dev server restarted).The Angular CLI's builder handles this case (it watches the Sass
loadedUrls), so projects migrating to this plugin lose partial watching silently, which is easy to misdiagnose as an application bug. In our app the shared partial is included by a dozen component stylesheets, and edits to it were invisible.Root cause
resolveResourcesruns eachstyleUrlthrough Vite'spreprocessCSS, which already reports every file the preprocessor loaded inprocessed.deps, but the plugin discarded that field. Transitive deps were therefore never registered inresourceToComponent, sohandleHotUpdatefell through to Vite's default pipeline (which has no module for them either), and theresourceCacheentry for the compiled style was never invalidated.Fix
processed.deps(normalized) per compiled style, cached alongside the compiled CSS so cache hits re-register them and the transform's prune loop does not drop them.resourceToComponentkeeps a single owner per resource, and a shared partial belongs to many components; with a single owner only the last transformed component would receive the update.handleHotUpdate, when a changed file is a known style dep: drop the compiled-CSS cache of every owning style and dispatch component HMR for each owner (the@ng/componentendpoint already re-reads and re-preprocesses styles from disk, so the served update is fresh).Tests
New
style-deps-hmr.test.ts, reusing the harness style ofhmr-hot-update.test.tswith a real resolved config so Sass actually runs and reports its deps:angular:component-updatefor both and returns[];ctx.modules).Adds
sassas a devDependency for that test.pnpm test: 202 passed (12 files).oxfmt --checkclean; theoxlint --type-awarefailure one2e/app/vite.config.tsis pre-existing onmain.Also validated end-to-end against a real application (large Angular admin, Sass partial shared by ~10 components): before the patch edits to the partial were never picked up; with it, each edit recompiles the owning styles and hot-updates every owning component within a couple of seconds.