exhibitionist-digital / ultra

Zero-Legacy Deno/React Suspense SSR Framework
https://ultrajs.dev
MIT License
2.99k stars 66 forks source link

Question about CSS modules #219

Open AlexJeffcott opened 1 year ago

AlexJeffcott commented 1 year ago

First off, I think I really like Ultra so thanks a bunch for making it!

I was wondering whether there was guidance or plans or thoughts regarding CSS modules?

The handrolled solution for “server with streaming bundling / compilation of SSR Preact” I am involved with uses a custom esbuild plugin for LightningCSS. This allows the initial SSR view to ship only the CSS which is used for that view and to do:

const classes = cssModule(new URL('./card.module.css', import.meta.url)) where cssModule is the helper function, <div class={classes.card}> to output <div class="jPBP8W_card">. The card.module.css file lives next to the card.tsx file.

I feel like this is a fast and powerful solution which has pretty good ergonomics.

deckchairlabs commented 1 year ago

I started an experiment that was just like this a while back, but I never took it any further. I'd be super interested in getting CSS modules supported in Ultra.

I'd be interested to see this esbuild plugin, and how they implemented it.

mashaal commented 1 year ago

I know you are referencing the prior implementation of CSS modules, but there is work being done in native-land as well, which I am incredibly excited for...

https://github.com/denoland/deno/issues/11961

https://web.dev/css-module-scripts/

deckchairlabs commented 1 year ago

I know you are referencing the prior implementation of CSS modules, but there is work being done in native-land as well, which I am incredibly excited for...

denoland/deno#11961

https://web.dev/css-module-scripts/

Unfortunately would still have to wait for Safari to support it https://caniuse.com/mdn-api_document_adoptedstylesheets

AlexJeffcott commented 1 year ago

I would say that an approach which is as 'native' as possible to scoping styles to es components is preferable.

In reflecting on the problem that css modules attempts to solve, I would not say that the standard approaches to css module plugins (inject an object as a map of original to hashed classes in the module scope and then transforming the css files in a separate pass) are necessarily the most pleasing, particularly with the fake import "styles.css".

I was thinking of making an esbuild plugin that would use of css module script style imports, which would hopefully get better support over time, and then, as a fallback depending on support in targeted browsers, inject the css string as a constructed stylesheet. I might have to wait esbuild to re-release the json equivalent, though.

What are your thoughts on 2 different approaches to appending a hash to classes etc:

mashaal commented 1 year ago

Unfortunately would still have to wait for Safari to support it https://caniuse.com/mdn-api_document_adoptedstylesheets

Did you see this is currently in Safari TP?