frankstallone / astro-cube-boilerplate

30 stars 2 forks source link

Removing unused css component classes #2

Closed chrismwilliams closed 6 months ago

chrismwilliams commented 6 months ago

Hi,

I hope you don't mind me opening this but I've had a very similar internal boilerplate like this running for a while, and thought I'd share that you can remove unused classes by using tailwind.

Essentially, I ended up adding any component classes to tailwinds @components layer. So in src/css/global.css you could change it to:

@import 'components/box.css' layer(components);
@import 'components/cluster.css'  layer(components);
@import 'components/flow.css'  layer(components);
@import 'components/grid.css'  layer(components);
/* ...other components */

Any unused classes then get compiled away.

It is a bit tedious repeating layer(components), I also hit #1 which is frustrating, and ended up creating an index.css file for components and importing everything into there. Then in src/css/global.css just having:

@import 'components/index.css' layer(components);

Hopefully that's clear, I can open a pull request if it make's it easier but thought I'd open this first to see if it's useful.

chrismwilliams commented 6 months ago

Closing as per commit e34fd9a

frankstallone commented 6 months ago

Hey Chris, I didn't realize you opened a thread here, too. I thought it was just the one on Set Studio's repository!

I think this is helpful, even if it includes more than blocks. Still thinking more about your considerations from the other issue.

chrismwilliams commented 6 months ago

Hi Frank, that's okay.

Hope you don't mind me explaining my thoughts here as well, I know it's a bit of a pain it covering 2 issues, but this is more Astro specific in a way.

TBH thinking about it more, I would probably do the same as e34fd9a here as well, just because it covers more use-cases. But it's quite interesting, to me anyway, how Astro and CUBE can be used together.

I mentioned that it might not work in Set Studio's case by applying /blocks to layer(components), just because the starting point was Andy's post about wanting to add a bunch of layouts to /components, and to only include ones on-demand, which is the perfect use case for layer(components). layer(components) being a filter, like Array.prototype.filter(), where you chuck a bunch at it, and it will include everything that's used.

Still thinking more about your considerations from the other issue.

I guess it's down to how you implement /blocks and expectation. I tend to view them as styles that are required, generally unique for each project, in the knowledge that everything inside that folder will be used, although implicitly. Hence, me personally not adding them via layer(components).

With that said, and mentioned on the other issue, I noticed that as I added more styles into /blocks, Astro would bundle everything into a single CSS file, for every page regardless.

I didn't really like that, but also understood that /blocks contained many types of styles:

So I ended up dividing them, should they be global or not. Site-wide block styles still go into global.css.

The CSS optimization you're talking about with Astro is coupling the CSS in the component itself, in the style tags — correct?

Not quite, rather importing required block(s) into the component/page/layout. It's definitely more hands-on, not for everyone, and TBH, if it wasn't for #1, I may not have 1. found this or 2. even cared due to time. It may even flip if/when it gets fixed.

By doing the above, Astro can create page specific CSS, which will/can be inlined depending on your config, and reduce the overall main bundle size. The other obvious being that if for example an <input/> in .contact-page needs changing, only the contact pages' styles change.

Ultimately, it comes down to your use case:

  1. If you see /blocks the same as components (where styles may/may-not get used), import everything into global.css and use layer(). It's quick and just works.
  2. If you're going to use everything in /blocks and it's a small project / or not a growing concern. You probably don't need to use layer(), not that it matters, and just import everything into global.css.
  3. Is where I'm currently residing, where I expect to use every block, so I don't use layer(). Blocks that are global in use are imported into global.css, and then the others are imported into components/pages/layouts.

Sorry for the long reply, it's a bit ott and it's weird some of the rabbit holes we end up in, that's how I found it really. I've just discovered that you can affect the compiled CSS, by both adjusting the groups array in tailwind.config.ts along with the import order in global.css 🫠.

But hopefully that makes sense and helps in some way. I'm sure Andy mentioned somewhere about making a starter/demo along with the re-design of cube.fyi. I'm interested in seeing how others end up using it.

frankstallone commented 6 months ago

Chris I really appreciate your level of detailed thought here. No need to apologize!

I agree that different levels of abstraction are better for different use cases. I may end up writing some documentation in the global.css file that speaks to these types of options. Are you okay if I pull some of your thoughts here into that?

I am also interested in seeing what ends up happening with cube.fyi!

chrismwilliams commented 6 months ago

Thanks, yeah absolutely!