svelte: scoped style doesn't work if compile component with css option 'none'
Describe the bug
As #7914 said:
When hydrating SSR components, the styles are commonly already generated and there is no need to generate it again for the client side bundle.
However, {css:"none"} does not work well with scoped styles.
Reproduction
Currently, the REPL doesn’t support none (and I created a PR to support it https://github.com/sveltejs/sites/pull/460).
Let’s just consider the following code snippet:
<div> red </div>
<style> div { color: red } </style>
We can compile this code using {generate: "dom", css: "external"} to obtain two output that are used for CSR:
/* output.css */
div.svelte-d8zsiy{color:red }
/* output.csr.html */
<div class="svelte-d8zsiy">red</div>
And then we re-compile this code using {generate: "ssr", css: "none"}, there will be no CSS or scoped class name generated.
As a result, the output.css file will not be applied to the SSR HTML:
# output.ssr.html
<div>red </div>
With {css: "none"}, the style is completely ignored, which means that Svelte cannot calculate the hash for the scoped class name.
A simple solution to this problem is to use {generate: "ssr", css: "external"} to generate the HTML for SSR.
But, as you can see in the REPL, all CSS are contained in the JS output, resulting in a larger bundle size.
Although bundle size for SSR might not be a problem in many cases, it could be beneficial to remove these unused CSS in JS output. (TBH, in my case, I run svelte inside the service worker, which means bundle size is critical.)
I propose that we reopen #2360 as it provides a simple and effective solution to remove CSS from the JS output.
Logs
No response
System Info
svelte 3.58.0
Severity
annoyance
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15 (11 by maintainers)
I’m tempted to make the change that when css is set to
externalthat the css is not filled in 4.0.1 and mark it as bugfix with the extra leeway that we just did breaking changes so one that _could theoretically _ be seen as one is okThe svelte playground has been upgraded, enabling us to illustrate the problem more conveniently now. Let’s use https://svelte.dev/examples/styling as an example.
This is the matrix illustrating how the option affects the JS output.
append_styles) and class (attr)attr)As you can see,
css: injected/externaldoes not affect the JS output.My proposal is to remove css from the JS output when we use
{generate:"ssr",css:"external"}, similar to what we did with{generate:"dom",css:"external"}.The goal is very similar to what we did with #7914, which introduced
css:noneto remove both css and class. However, I want to keep the class to avoid breaking the scoped CSS.From my perspective, I believe that this change is not a significant breaking change. People who want to generate both css and class could use
{generate:"ssr",css:"injected"}to keep the original output.cc: @dummdidumm