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

Importing CSS as string shouldn't also inject it into HTML's head #3246

Closed
6 tasks done
tbroyer opened this issue May 3, 2021 · 10 comments
Closed
6 tasks done

Importing CSS as string shouldn't also inject it into HTML's head #3246

tbroyer opened this issue May 3, 2021 · 10 comments
Labels
enhancement New feature or request

Comments

@tbroyer
Copy link

tbroyer commented May 3, 2021

Describe the bug

When importing a CSS as string, e.g.

import styles from "./styles.css";

the CSS is also extracted into a CSS file and injected into the HTML's head.
This means that the CSS is duplicated as both "pure CSS" and a JavaScript String. This cause bloats and could also cause conflicts if the strings are intended to be injected into shadow doms, isolated from each another (a .foo selector in one shadow dom can be a completely different .foo in another one, and of course of a .foo in the main page; those isolated stylesheets could also use element selectors: a, etc. as they're intended to be isolated into a shadow dom).
The JS String is also not minified, which contributes to the bloat.

I can't see a reason why one would want both behaviors at the same time, and even then there would also be an easy workaround if one really wanted it:

import "./styles.css"; // inject the stylesheet into the HTML
import styles from "./styles.css"; // get the stylesheet's content as a JS string

(this is why I'm filing this as a bug report; feel free to reclassify as a request for enhancement)

Reproduction

See https://github.com/covidtrackerfr/vitemadose-front, deployed at https://vitemadose.covidtracker.fr
The project imports the styles as string to inject them into web components' shadow DOM.

The styles/global.scss here is duplicated both in the generated assets/index.*.css and as a JS string, but that's expected as it's imported both "for side-effects" (import "./styles/global.scss", to apply to the HTML page content) and "as string" (import globalCss from "../styles/global.scss", to be injected into web components' shadow dom, as they're isolated from the page).
(this is bad as it leads to 222KB of duplicated content, but that's another issue, unrelated to Vite; the JS string is not minified CSS though, with >11KB of line breaks, and I haven't even looked at white space; this probably deserves a separate issue though).

All other stylesheets are only imported as strings, but they also end up in the assets/index.*.css file, unnecessarily. In this project, fortunately (or because they've been coded that way as a workaround), they don't cause conflicts, only bloat.

System Info

Output of npx envinfo --system --npmPackages vite,@vitejs/plugin-vue --binaries --browsers:

  System:
    OS: Linux 5.11 Arch Linux
    CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
    Memory: 877.99 MB / 15.52 GB
    Container: Yes
    Shell: 5.1.4 - /bin/bash
  Binaries:
    Node: 16.0.0 - /usr/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 7.11.2 - /usr/bin/npm
  Browsers:
    Firefox: 88.0
  npmPackages:
    vite: 2.1.5 => 2.1.5 

Used package manager: npm


Before submitting the issue, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the docs.
  • Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
  • Provide a description in this issue that describes the bug.
  • Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/vue-next instead.
  • Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
@patak-dev patak-dev added enhancement New feature or request and removed pending triage labels May 3, 2021
@patak-dev
Copy link
Member

For reference, there were already some discussions about this in this PR #2148 (comment)

@tmayr
Copy link

tmayr commented May 11, 2021

Sort of a +1, same use case regarding shadow-dom.

And at least in my use case, using the CSS as string not only duplicates the output as @tbroyer mentions, but also, HMR doesn't seem to trigger on the string on updates. Maybe this should be filled as a different bug tho. It's just a bit more obvious when dealing with shadow-dom, as the update only appends to <head> and not visible at all to the shadow-dom.

@franktopel
Copy link

franktopel commented Jul 19, 2021

This makes Vite essentially a non-option when developing web components.

What we've been using when configuring our previous build stack was explicitly excluding files named *.shadow.css from being bundled into the css bundle for the whole application.

Maybe such a convention-based configuration option would make this easier to implement?

css: { exclude: ['**/*.shadow.css'] }

This would still allow bundling CSS for web components/modules that don't use shadow DOM or rely on the styling information from the light DOM (in case of web components using slots).

@franktopel
Copy link

franktopel commented Jul 19, 2021

Please consider implementing this in a way that seems likely to be compatible with the upcoming CSS module scripts.

@urapadmin
Copy link

Same problem here, importing sass into a lit component. All the styles occur additionally in a style.css. Could anybody find at least a workaround for the time being?

@tarnishablec
Copy link

Same problem here, importing sass into a lit component. All the styles occur additionally in a style.css. Could anybody find at least a workaround for the time being?

use ?inline and manually insert style string to component

@urapadmin
Copy link

Same problem here, importing sass into a lit component. All the styles occur additionally in a style.css. Could anybody find at least a workaround for the time being?

use ?inline and manually insert style string to component

I am not sure I understand. You mean I should write the css inline into the component directly instead of importing an external file?

@franktopel
Copy link

import styles from "./styles.css?inline";

@urapadmin
Copy link

import styles from "./styles.css?inline";

that is more than a workaround. It solves it for me. Thanks a bunch!

@patak-dev
Copy link
Member

Closing this issue. See e1de8a8 for reference 👍🏼

@github-actions github-actions bot locked and limited conversation to collaborators Nov 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

6 participants