Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HMR - Inlined css reports as page it was imported on and not as itself #232

Closed
ambrt opened this issue Dec 20, 2021 · 8 comments
Closed
Labels
bug Something isn't working triage Awaiting triage by a project member

Comments

@ambrt
Copy link

ambrt commented Dec 20, 2021

Describe the bug

When inline importing css

import front from "./front.css?inline"

And editing it, HMR reports edit of .svelte file where it was imported.

[vite] hmr update /src/routes/index.svelte (x3)

Reproduction

Install:
https://github.com/ambrt/inline-css-bug-vite
npm run dev

Go to front.css and edit or just save.

HMR should report front.css as being edited but its reporting index.svelte

(Additionally there's alert on running page with Vite API data)

Logs

No response

System Info

System:
    OS: Linux 5.4 Ubuntu 20.04.3 LTS (Focal Fossa)
    CPU: (2) x64 Intel(R) Core(TM)2 Duo CPU     E8400  @ 3.00GHz
    Memory: 238.66 MB / 7.77 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 16.2.0 - ~/.nvm/versions/node/v16.2.0/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 8.1.4 - ~/.nvm/versions/node/v16.2.0/bin/npm
    Watchman: 20201115.021953.0 - /usr/local/bin/watchman
  Browsers:
    Chrome: 91.0.4472.164
    Firefox: 95.0
  npmPackages:
    @sveltejs/adapter-auto: next => 1.0.0-next.4 
    @sveltejs/kit: next => 1.0.0-next.202 
    svelte: ^3.44.0 => 3.44.3

Severity

blocking an upgrade

@ambrt ambrt added bug Something isn't working triage Awaiting triage by a project member labels Dec 20, 2021
@ambrt
Copy link
Author

ambrt commented Dec 21, 2021

Problem is appearing in Vite API import.meta.hot.on("vite:beforeUpdate", (data) => {}) which is exactly problem that i have.
path value shows as index.svelte and not front.css.
(I use it to switch custom store value based on file being saved in editor)

@bluwy
Copy link
Member

bluwy commented Dec 22, 2021

Hi, can you explain the reason you're using the ?inline suffix for CSS file? I think it should be avoided as it isn't explicitly documented in Vite docs. @dominikg also found that ?inline modules doesn't have HMR by default. So any change in the CSS file would "bubble" up, meaning the Svelte component would accept the HMR instead, leading to the behaviour you mentioned.

@ambrt
Copy link
Author

ambrt commented Dec 23, 2021

It's basic use is in switching themes with css files and with $theme store var.
The way I do it is that i put css into variables (inlined import) and then activate one base64 encoded into svelte:head.
<link rel="stylesheet" href="data:text/css;base64,{css}" />

I make css var reactive to $theme var change.

Importing css files without inline suffix loads all csses into dom and as far as I'm concerned in order of importing - so changes to first css are overwritten by 2nd even with correct hmr of first one.

One perk of having inlined css is that you can store name of theme in css filename and automatically change theme by editing css and listening via import.meta.

This way csses edits and $theme var become synchronized and allow for quicker developing of different layouts.

@bluwy
Copy link
Member

bluwy commented Dec 23, 2021

Thanks for the explanation. It still seems to me that this issue is intended behaviour from Vite side, unless they plan to publicise ?inline. If I understand correctly, ?inline works the same as ?raw? Though ?raw has a bug now until vitejs/vite#5796 is merged. I also made a stackblitz with a ?url example. Though that has a bug as well until vitejs/vite#5940 is merged. If these alternatives would work for your usecase, I can try to push I get those two PRs fixed.

@dominikg
Copy link
Member

Hmm, adding style nodes to the component template like this isn't ideal. Wouldn't style props help to build themable components that react to changes?

https://svelte.dev/docs#template-syntax-component-directives---style-props

Or just some service/helper that updates them in a generated style node with :root if this is about theming

@ambrt
Copy link
Author

ambrt commented Dec 28, 2021

@dominikg I work on rather edge case b/c i test layouts of different sites in one frontend code base. I find having one main css file per theme/layout and then have more specific styles in each component as more clear to think about and to apply changes, be it small or overhauling. Using one css file allows me to edit all necessary classes in one go instead of switching to each component and doing edits in it's <style> section.
Maybe i don't get advantages of style props in this case.

@bluwy The example from stackblitz is doing closest to what i seek. Even without bugs you mentioned being fixed, ?url and inserting it into svelte:head with conditions is correctly sending filename, updates css in dom and doesn't leave previous theme's classes.
I adopt this approach. There are to caveats:

  • In SSR all benefits of importing with ?url are gone, meaning a full css import is done and combination of all imported csses is visible. So if production requires different layouts, it has to be done in base64 way mentioned earlier to avoid flash of different styles.
  • There should be leading slash in href in <link rel="stylesheet" href={"/src/assets/light.css" || lightCss} /> so it will resolve from root of project. Otherwise browser will look for relative path like /user/123/src/assets/light.css etc.
    (I think previous stackblitz version was without leading slash).

Hard coding path to style is sufficient in my case, so there is no big need for pushing vitejs/vite#5940.

Thanks for posting this solution.

@dominikg
Copy link
Member

glad there is something that works for you. Closing the issue as the described behavior is "working as intended" from our perspective .

Maybe you could also use svelte-preprocess external files feature to keep the css in a separate file and still benefit from scoping

https://github.com/sveltejs/svelte-preprocess#external-files

@bluwy
Copy link
Member

bluwy commented Dec 29, 2021

I would be cautious using ?url for css files. I found out recently that Vite doesn't fully support it, since CSS files aren't chunked (I think), so there may be bugs. Though I'd still avoid ?inline and probably use ?raw instead, but you have to wait for vitejs/vite#5796 to be merged first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working triage Awaiting triage by a project member
Projects
None yet
Development

No branches or pull requests

3 participants