vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.62k stars 6.2k forks source link

Inline CSS for any npm package injected into head of host app instead of the web component's Shadow DOM #11769

Open mariojankovic opened 1 year ago

mariojankovic commented 1 year ago

Describe the bug

I'm attaching my react instance into a web component and it's styles are being added to that component's shadow DOM. I've been using the ?inline flag for any styles I use with my React but the issue is any external module (let's say a component library like React's Material UI) will inject it's styles into the host app's head and mess up any classes that bear the same name as that component library. Any tailwind based libraries are a great example as they have classes like container that can co-exist in other apps very easy and will break them.

Some libraries do offer individual styles or scoped CSS, but some don't and since I'm using this in a fairly large React I need a way to disallow injecting styles to my host app. So in short, I need vite to push those stlyes to my web component's shadow DOM somehow.

Reproduction

https://stackblitz.com/edit/vitejs-vite-htcrgj?file=src%2FApp.jsx,src%2Fmain.jsx&terminal=dev

Steps to reproduce

  1. npm install
  2. npm run dev
  3. Import a library like Material UI into a web component with Shadow DOM
  4. Styles are injected into the head of my host app instead of the shadow DOM of my web component and they mess up existing CSS

System Info

System:
    OS: macOS 12.6
    CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 770.31 MB / 32.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 18.10.0 - ~/.nvm/versions/node/v18.10.0/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v18.10.0/bin/yarn
    npm: 8.19.2 - ~/.nvm/versions/node/v18.10.0/bin/npm
    Watchman: 2022.03.21.00 - /usr/local/bin/watchman
  Browsers:
    Chrome: 109.0.5414.87
    Firefox Developer Edition: 109.0
    Safari: 16.0

Used Package Manager

npm

Logs

No response

Validations

patricknelson commented 1 year ago

@mariojankovic is your build compiling to umd or iife, by chance? I noticed this issue as well in https://github.com/patricknelson/svelte-retag/issues/6 but it only happens when compiling to anything that's not es or cjs. Asking since I think maybe it's caused by the code here (pinned to 5.x for posterity):

https://github.com/vitejs/vite/blob/v5.0.0-beta.3/packages/vite/src/node/plugins/css.ts#L673-L676

I wonder if maybe we could somehow configure host element that this .appendChild() could be called on, instead of always being on document.head.appendChild? 🤔

mariojankovic commented 1 year ago

I wonder if maybe we could somehow configure host element that this .appendChild() could be called on, instead of always being on document.head.appendChild? 🤔

@patricknelson that's exactly what we need. A way to define what host we want to use for HMR injected styles. I ended up targeting this thing differently but I think it's still valid as I'd like to go back to shadow DOM.