Legacy apps / webcomponents and issues with CSS HMR in Vite - HMR api #4585
Replies: 2 comments 3 replies
-
|
As a quick proof-of-concept test I went in and figured out how vite's css transform plugin worked, and added support for a "?rawjs" in my fork. This largely worked in HMR, as it just provided the default export and does not call the update css, now I'm sorting out how I would make this work in a build context, as this is a vastly different topic than the import. |
Beta Was this translation helpful? Give feedback.
-
|
I assume this is a Rollup-level issue rather than Vite, but Webpack's |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Background info: (TL;DR; below - you can skip this and go straight to the issue - avoiding X/Y conversations)
I'm working on a large legacy app and we're using Vite to help bring in some modernizations.
( There's several overlapping technical concerns here, it's hard to know how much is important. I'd rather not ramble on about all of it I'm just going to explain our current approach which is already long enough. If there's a question about the 'why' I can try to answer that )
We ultimately want a react app, currently we have a lot of conflicting legacy CSS/JS and libs - and my approach to modernizing this was to isolate from the existing CSS by building web components. For now due to other issues, we're using preact. We're creating a simple boot strap web component and rendering preact to the shadowroot, with a closed dom.
Initially I created a scaffold that builds the bare minimum web-component, and renders the preact component - we have a few of these in our system as initial entry points, where the developers can point to them asking for the web component, and it's all working just fine. Each of these components are referenced in the rollup/input as entrypoints to bundle
I've been wanting to largely get HMR working on this setup, as it would help modernize our development environment. For now we can ignore the HMR stumbling blocks I've had with the react/preact side as I have them "good enough" atm for myself.
BUT I've ran into so many issues with the CSS.
Vite assumes that all CSS must be included in the of the document. This largely doesn't break things in our environment, especially if I use a css module, because of the uniquness of the class names, etc - I have no issue that specifically but ... these css stylesheets are inaccessible to the webcomponent for ... obvious reasons. To wit I've been trying to make them accessible in some fashion. But I cannot find any hooks in the Vite api that work.
Originally I tried to import them as css modules, doing this there is no way to get the style sheet content in any reasonable way.
I decided to try to just import the CSS as raw text, as this would work "good enough for us for now" - And create these style sheets in the root of the shadow dom, calling it good.
And this does work, initially - but the HMR for a css files never triggers for me.
TL;DR; (oh damn this is long itself...)
CSS files are compiled into a javascript blob that calls the Vite function to update the css in the head, and they call import.meta.hot.accept themselves. When a js module accepts itself, any file importing it cannot actually intercept THAT files hmr event...
This is largely the same effect of what happens when importing CSS files. I vetted this by making a simple vite test app, it does in-fact work this way blocking the parent's hmr triggers using just pure js like my above example. And this absolutely makes sense from an HMR stand point, one an only one trigger need be called per file, it would be weird to do otherwise.
Lastly I figured "I'll just rename the files to txt" and... well that didn't help me at all either, because this just causes a full page refresh... there seems to be no way to hook the raw txt file? and I sorta stopped debugging at that point.. because this seemed like a fools errand
So I'm stumped, I'd love to have some ideas on how to hook the full CSS text so I can make some form of my own implementation of how CSS should be loaded, instead of the current implementation.
Maybe there's a pathway in the plugin system to do this?
One of the simplest ways would be to add an option in the Vite config for css, to eliminate the "import.meta.hot.accept()" lines and make vite not load css initially, treat it as some form of compiled js module. (* vite, seems to also load the css imports BEFORE any other files in the module system, which makes sense from css/FOUC standpoint )
This would by and large be the quickest and easiest way to do this.
Example:
Another option could be to expand upon the above idea - but more fully seperate the concerns of HMR and the loading of CSS. I'm a bit out of my depth here - but I think this could be achieved within the client side vite context, as the current default updateStyles could be added to that, and then referenced there, then api the consumer could overwrite that with their own implementation, which may be a great win/win/win all around. And I'm quite partial to an approach like this. (But I'm not sure I have the full enough understanding of Vite to implement it.)
Thank you for those who read this, it was quite long winded.
Beta Was this translation helpful? Give feedback.
All reactions