toastdotdev / toast

The best place to stack your JAM. Toast is a Jamstack framework
153 stars 13 forks source link

CSS/PostCSS/CSS Modules #18

Open ChristopherBiscardi opened 3 years ago

ChristopherBiscardi commented 3 years ago

There are a few approaches to CSS to support. I'll call out specific libraries that represent various approaches.

Emotion

Emotion mostly "just works". The main problem right now is that they don't ship ESM-compatible releases for the node.js v14 environment. There's an example of a working emotion package here and it is the same as the source code with two changes: the Flow types are removed and the imports have .js added to them.

Once there is an esm build of emotion, it will work by default with no additional required config.

Linaria

Linaria represents "css-in-js with static extraction".

Approach to this in Toast is TBD because it uses a custom babel plugin. I don't know if we want to replicate it or if we should, etc. There are plenty of other CSS approaches.

CSS Modules

turns import styles from './whatever.css'; into an inline JSON object with style names and hashes, while also compiling the CSS into files.

It is likely that this will require running a PostCSS server and communicating to it. Totally doable, although will need us to code support for it in Toast.

Tailwind

Works today with PostCSS-cli without needing anything from Toast.

The interesting problem here is "how do we hot-reload styles" in development server situations

Raw CSS Files

include the urls in link tags, write your CSS in the static folder (or compile it into /public with sass, etc). No special work needed.

ChristopherBiscardi commented 3 years ago

re: linaria, there are other css-in-js babel plugin based libraries coming out all the time as well: https://github.com/atlassian-labs/compiled. It's possible that swc gets the ability to convert to and from babel ast in the future, but not guaranteed.

ChristopherBiscardi commented 3 years ago

Should we align with the asset-references proposal?

-- source and some more commentary

talves commented 3 years ago

Is there a way to use compiled now in our workflow with Toast?

Asking for a friend. 🤣

ChristopherBiscardi commented 3 years ago

If you use setDataForSlug and preprocess the javascript you can do whatever you want to it. There's no example site using compiled though so you'll have to come up with that on your own. It's the same concept as mdx in toast-tools

talves commented 3 years ago

I'll definitely look at it. Been meaning to look at compiled and doing that in Toast would be a good place to do that.

ChristopherBiscardi commented 3 years ago

import assertions are stage 3 (as opposed to assert references, which hit stage 1 two years ago. import assertions might fit with the browser-native idea of what css modules are as well

ChristopherBiscardi commented 3 years ago

Continuing the import assertions path, here's a proposal for prefixes that includes css modules, url, url-inline, etc

https://docs.google.com/document/d/1BObemtyKibEYKZPuu5YqHlam6gRSA42oqPMnuSGHcTs/edit?usp=drivesdk

From _developit

dangvanthanh commented 2 years ago

Hi @ChristopherBiscardi

I use PostCSS and Tailwind, too. Currently, I using watchexec to hot reload assets. Is this a way to using for hot reload?

ChristopherBiscardi commented 2 years ago

@dangvanthanh possibly useful yeah! Thanks for the link, it looks like that can be used to do file watching without having to roll our own on top of notify. We need the dev server implementation to land first (I'm rewriting the processing pipeline now for that), then it would be easy to implement live-reloading (full refresh of the page). After that the next step for hot-reloading (just re-inserting the JS) of css would be to remove and re-insert the styles in the browser.

In the meantime, some people are chaining cli tools like this together (postcss-cli has a watch command, for example).

ajstrand commented 2 years ago

@talves have you been able to implement something like the "compiled" library on your toast site yet? I'd be interested in moving to zero runtime css in js. I might try to whip up a quick example.

we can always colaberate on this as well if you're interested.

ChristopherBiscardi commented 2 years ago

it's worth noting that SWC is implementing a full CSS parser, including a Rust implementation of Stylis, the underlying lib behind styled-components/emotion/etc

https://github.com/swc-project/swc/tree/b3fd7046d7eb678fa5b688db920cec03913b3276/css

My guess is that if we build static extraction that building on top of this work would be the best way to do that.

talves commented 2 years ago

if we build static extraction that building on top of this work would be the best way to do that.

Agreed.

ajstrand commented 2 years ago

So i spent way too much time last night trying to integrate compiled w/ Toast, just to see if I could.

I can transform/build the styles ok and see what the results look like, but the @compiled/react plugin throws an error when I try and run Toast w/ the preprocessed code. If i can fix that error, it may be possible to use the compiled lib w/ Toast.

this is all experimental though.