astroturf icon indicating copy to clipboard operation
astroturf copied to clipboard

Using in a shared component library

Open danny-andrews-snap opened this issue 5 years ago • 7 comments

A major sticking point for people with zero-runtime CSS-in-JS solutions (e.g. css-modules) has been around code-sharing. The import styles from './styles.css'; is problematic since its not a standard node module.

Currently, I see a few (unideal) options:

  1. Pre-compile the styles before publishing the shared component, and distribute the component JS and namespaced CSS separately.
  2. Distribute the component as-as, requiring consumers to deal with transforming the CSS Module imports.

The benefit of #1 is that your consumers don't have to use css-loader. The downside is they have to manually import your pre-build css file.

@ai and I discussed and a good solution might be a babel version of style-loader. More context: https://twitter.com/lunde_andrews/status/1034116264774516737.

danny-andrews-snap avatar Oct 16 '18 15:10 danny-andrews-snap

If you use the Babel transform per https://github.com/4Catalyzer/astroturf#use-without-webpack, you'll end up with a bunch of little split-out CSS files.

You'd need to either do something BEM-y in naming the classes, though, or else have your users apply the module transform (perhaps based on extension?) to the extracted CSS, or else risk class name collisions.

taion avatar Oct 16 '18 15:10 taion

Yeah, that's basically the #2 option. Certainly works, just not as automatic as it is with solutions like styled-components. Also gets a bit hairy when doing SSR.

You either have to use css-loader/local or something like css-module-require-hook.

danny-andrews-snap avatar Oct 16 '18 15:10 danny-andrews-snap

We definitely could provide a preset perhaps for this use-case. Postcss is doing the css-modules work, so one option is to write out or inline the json map of the css classes and then write the css out as normal.

Internally we do use this for shared libraries with just the babel plugin outputting css files, however it does depend on the consumer using webpack with css-modules setup in order to work. I do think it's probably worth putting together a recipe or simple cli for supporting this use case tho!

jquense avatar Oct 16 '18 15:10 jquense

Postcss is doing the css-modules work, so one option is to write out or inline the json map of the css classes and then write the css out as normal.

In this case consumers would have to manually require the css for all the components they are using, no? This would be pretty brittle, as you would have to keep those in sync (e.g. you decide to use DatePicker from your shared component library and now you need to add @import '~/my-library/components/DatePicker/styles.css'; to index.css).

p.s. This is probably not a trivial problem, because I have yet to see a really good solution come from the css-modules camp for this. However, it seems not insurmountable. :)

danny-andrews-snap avatar Oct 16 '18 15:10 danny-andrews-snap

In this case consumers would have to manually require the css for all the components they are using, no?

I mean no more so than any other stylesheet based library right? we don't want to auto import and append to the DOM b.c that would remove a consumers ability to extend or consolidate. The only really "clean" approach has to assume the user is using webpack, ideally webpack would also provide someone way for libraries to specify configuration, a feature that's not ever gotten added yet :/

jquense avatar Oct 16 '18 15:10 jquense

we don't want to auto import and append to the DOM b.c that would remove a consumers ability to extend or consolidate.

I think many would prefer to sacrifice some flexibility for convenience/robustness (look to the success of styled-components for proof). The ability to import a component (HTML + JS + CSS) as a complete unit is extremely powerful. However, I'm inclined to agree with you that the best approach currently is to assume the consumer is using webpack with the correct config. Maybe when this lands, we'll have a better solution: https://medium.com/webpack/the-new-css-workflow-step-1-79583bd107d7. :)

As far as extension is concerned, that can be done through https://github.com/javivelasco/react-css-themr or just simple className props, no?

danny-andrews-snap avatar Oct 16 '18 16:10 danny-andrews-snap

I solved this problem using direct specifying loaders for CSS import and exception astroturf/loader. import '!!astroturf/loader!style-loader!css-loader!react-day-picker/lib/style.css'

Asrover avatar Aug 09 '19 14:08 Asrover