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

[Bug]: Does it work with shadowroots? #1036

Open
1 task done
telion2 opened this issue Dec 6, 2022 · 0 comments
Open
1 task done

[Bug]: Does it work with shadowroots? #1036

telion2 opened this issue Dec 6, 2022 · 0 comments
Labels

Comments

@telion2
Copy link

telion2 commented Dec 6, 2022

Describe the bug

So I have wrapped a vue3 application into HTMLElement and put it into a shadowRoot there.

Because of this, the Styles are now loaded in a more atypical way:

class shadowWebcomponent extends HTMLElement {
  public shadowRoot: ShadowRoot;
  private shadowApp: VidisLoginApp;
  constructor() {
    super();
    this.shadowRoot = this.attachShadow({ mode: "open" });
    this.shadowApp = document.createElement("div");
  }
  ...
  connectedCallback() {
         ...
         this.shadowApp.app.mount(this.shadowApp);
  }
  ...
 appendStyles(): void {
    const internalStyles = [
      require("!!./to-string-loader!css-loader!primevue/resources/primevue.min.css"),
      require("!!./to-string-loader!css-loader!/node_modules/primeflex/primeflex.css"),
      require("!!./to-string-loader!css-loader!primevue/resources/themes/tailwind-light/theme.css"),
      require("!!./to-string-loader!css-loader!sass-loader!primeicons/primeicons.css"),
      require("!!./to-string-loader!css-loader!sass-loader!./assets/scss/globals.scss"),
    ];
    for (const style of internalStyles) {
      this.appendStyle(style);
    }
  }
  appendStyle(style: string): void {
    const element: HTMLElement = document.createElement("style");
    element.innerHTML = style;
    this.shadowApp?.appendChild(element);
  }

...
customElements.define("nameOfShadowWC", shadowWebcomponent);

So in other words the styles are loaded by appending a style tag into the shadowRoot.

My question is: Can PurgeCSS detect such styles because something like document.querySelector('...') will not work.
Usually, you need first to find the shadowRoot Tag and then run the selector on the shadowRoot to find the element of interest.

My second question is: Can PurgeCSS find styles appended by appending a style Tag with appendChild()?

Basically, my Issue is, that the big CSS Modules are not being purged. I've seen that PurgeCSS feature so-called Extractors.
So my question is: Is the solution for me to implement an extractor for this scenario of shadowRoots and appendChild() or is the actual Issue that I need an extractor for specifically primevue, primeflex and tailwind?

To Reproduce

For my specific case:

  1. Create a vue App
  2. Create a HTMLElement and in there create a shadowRoot
  3. Mount the vueApp during the connectedCallback of HTMLElement
  4. After mounting, load the styles, by loading the styles through a css-loader and to-string-loader
  5. Wrap the styles into a style-tag Element
  6. append the style Tag to the shadowRoot.
  7. Build the whole thing by "build": "vue-cli-service build --target lib --name {NameOfApp} src/main.ts --inline-vue",

Expected Behavior

PurgeCSS can purge CSS loaded by appendChild() and added to shadowRoots.

Environment

Vue 3,
"@babel/cli": "^7.19.3",

Add any other context about the problem here

You may be asking, why do you load styles so weirdly?
Well, I needed the full power of Vue and I needed a web component. This web component will and can be used on any website and should therefore not interfere with the CSS of the "Host Page" where the Web component is embedded.

Thus I encapsulated the Vue App and the styles inside a shadowRoot. This caused a few other Issues, which finally got me the solution of appending a style Tag to the shadowRoot, which works perfectly.
Also, Vue, although supporting Web components, they do not support wrapping a Vue app with an HTMLElement without Issues with loading styles, so I needed to load them globally.

Now my Client wanted to reduce the build size which brought me to PurgeCSS.

I followed the guide here: https://purgecss.com/guides/vue.html
Which unfortunately was ineffective, so now being new to PurgeCSS I wondered if there is even a chance for PurgeCSS to work in such a scenario.

Code of Conduct

  • I agree to follow this project's Code of Conduct
@telion2 telion2 added the bug label Dec 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant