ProjectEvergreen / greenwood

Greenwood is your full-stack workbench for the web, focused on supporting modern web standards and development to help you create your next project.
https://www.greenwoodjs.io
MIT License
94 stars 9 forks source link

apply CSS optimizations and bundling to CSS (in) modules #1227

Open thescientist13 opened 2 months ago

thescientist13 commented 2 months ago

Summary

Coming out of #1199 / #1211 it would be nice to extend the optimization / bundling to native CSS files to "CSS in JS" like use cases, in particular thinking about Import Attributes / CSS modules, e.g.

/* header.css */
header {
  background-image: url('../images/webcomponents.jpg');
}
// header.js
import sheet from './header.css' with { type: "css" };

const template = document.createElement('template');

template.innerHTML = `
  <header>
    <h1>Welcome to my website!</h1>
  </header>
`;

export default class Header extends HTMLElement {
  connectedCallback() {
    if (!this.shadowRoot) {
      this.attachShadow({ mode: 'open' });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }

    this.shadowRoot.adoptedStyleSheets = [sheet];
  }
}

customElements.define('app-header', Header);

And ideally the background image would be bundled out the same way is would be if just in a regular CSS file.

Details

Part of the caveat here is that in our original solution for #923 , we still had to bundle CSS modules as a CSSStyleSheet and so this means that in all cases, the above CSS file would be a JS file, not a CSS file, and this would not be tracked by Greenwood's default CSS optimization detection, e.g.

const sheet = new CSSStyleSheet();sheet.replaceSync('header { background-image: url('../images/webcomponents.jpg');}');
export const sheet;

So, even if we were able to eliminate this for clients, SSR context would still need to have this handled, since NodeJS doesn't support CSS modules, so we definitely want to bundle there as well.

I suppose one way to handle the "CSS-in-JS" case would be to test if

Then we can run a JS AST over it, and optimize the CSS from there?


If we're doing full optimizations for CSS-in-JS, should we also consider extending this to @import rules in CSS, like is still being used in https://github.com/AnalogStudiosRI/www.analogstudios.net/pull/98 ? This would mean user's would no longer need to use the postcss-import plugin. 💯