Microbundle: recommendation for handling css

Created on 13 Jun 2019  路  12Comments  路  Source: developit/microbundle

hey - probably the wrong place for this, but with all the talk surrounding es:modules at the moment, I thought I might see if microbundle has a recommendation for library authors on how to bundle CSS.

css-loaders are amazing, but obviously you cant keep the require('my.css') within the JS for CJS or ESM/m.js type files. _but_ it would be nice not to have to make people import the css separately.

I'd be interested in hearing if microbundle has goto _standard practice_ in the area, or if there is anything _cool_ i can do so people don't have to import my-module in js then repeat the @import 'my-module/dist/my.css'?

Thanks

Most helpful comment

@ConsoleTVs I believe what Marvin was trying to say is that, within JS, the following is not part of ECMAScript specification, nor is 'importing' anything, that is not a JS file (perhaps excluding json).

const styles = require('./styles.css')

While in our files intended for the browsers, we can certainly use rollup plugins to allow the css to be extracted, the fact that that line exists in the JS file is against the spec. This means library authors are in a tough spot. Some would say we should not distribute JS files which include imports of css files, or anything that is invalid.

So, do authors distribute packages which has code that goes against spec and assume everyone can, and is able to, configure a suitable bundler so that the javascript is then valid and works. Or, do package authors stick to the spec and distribute files that work without the need for this extra step.

I have certainly taken the lazy approach for now. Our packages are not public, and we have a pre-configured bundler config which all our web apps use. This has allowed us to simply build and extract the css files (as you suggest), and then re-insert and const styles = require('./styles.css') at the top of the distributable package. Each package can consume other packages without having to manually worry about importing css separately. I say this is the lazy approach, as the import is invalid and only works with how we have configured rollup.

We could probably use a key in the package.json file to tell our bundler config that this .css file exists, which means we might be able remove the import completely. Then the author would have to remember to add this new, non-spec-compliant, key to the package.json file if they wish to export css. There is work being done in this area to allow esm and cjs files to be exported to the package.json - so this area could be 'hacked' for our needs. https://2ality.com/2019/10/hybrid-npm-packages.html

At this moment in time, I do not see a nice, spec compliant, way around it. Except for something like css-in-js, which gives the consumer the option of extracting it into a separate file if they wish. If they don't, then it should still function as valid JS

All 12 comments

@peter-mouland I know it's not helpful, but your current solution is what I do.

Without a spec for how CSS can be referenced from within a JS Module graph, I don't know that it's yet possible to automate this.

@developit Any update on this? Is it possible to just import './my.css' in my library's modules and not have consumers of my library have to import any css at all when using my react components.

Guys, I just want to simply import '../lib/my_styles.css' and not let the consumer have to to anything else; anyway to accomplish this?

That's not possible because there is no standardised way or spec that specifies how non-js files should be distributed in npm packages.

Therefore user's will always need to import the distributed css files themselves.

@marvinhagemeister Well, you're wrong. Rollup allows that, you just need rollup-plugin-postcss.

So the thing is, how can this support it?

The thing is that you guys set this line: https://github.com/developit/microbundle/blob/0317afd78902aaf25ef21c80534c032bdb8e6063/src/index.js#L432

This is true and therefore, the css file is extracted. People should be happy to control such an option.

@ConsoleTVs I believe what Marvin was trying to say is that, within JS, the following is not part of ECMAScript specification, nor is 'importing' anything, that is not a JS file (perhaps excluding json).

const styles = require('./styles.css')

While in our files intended for the browsers, we can certainly use rollup plugins to allow the css to be extracted, the fact that that line exists in the JS file is against the spec. This means library authors are in a tough spot. Some would say we should not distribute JS files which include imports of css files, or anything that is invalid.

So, do authors distribute packages which has code that goes against spec and assume everyone can, and is able to, configure a suitable bundler so that the javascript is then valid and works. Or, do package authors stick to the spec and distribute files that work without the need for this extra step.

I have certainly taken the lazy approach for now. Our packages are not public, and we have a pre-configured bundler config which all our web apps use. This has allowed us to simply build and extract the css files (as you suggest), and then re-insert and const styles = require('./styles.css') at the top of the distributable package. Each package can consume other packages without having to manually worry about importing css separately. I say this is the lazy approach, as the import is invalid and only works with how we have configured rollup.

We could probably use a key in the package.json file to tell our bundler config that this .css file exists, which means we might be able remove the import completely. Then the author would have to remember to add this new, non-spec-compliant, key to the package.json file if they wish to export css. There is work being done in this area to allow esm and cjs files to be exported to the package.json - so this area could be 'hacked' for our needs. https://2ality.com/2019/10/hybrid-npm-packages.html

At this moment in time, I do not see a nice, spec compliant, way around it. Except for something like css-in-js, which gives the consumer the option of extracting it into a separate file if they wish. If they don't, then it should still function as valid JS

For now, i had to swap a 20 lines long css file into inline styles for my lib. So yeah, not fancy anyway when I had it working with rollup...

While in our files intended for the browsers, we can certainly use rollup plugins to allow the css to be extracted, the fact that that line exists in the JS file is against the spec. This means library authors are in a tough spot. Some would say we should not distribute JS files which include imports of css files, or anything that is invalid.

So, do authors distribute packages which has code that goes against spec and assume everyone can, and is able to, configure a suitable bundler so that the javascript is then valid and works. Or, do package authors stick to the spec and distribute files that work without the need for this extra step.

@peter-mouland you said it better than I did! That's exactly the situation we're in 馃憤 We're siding with the latter and remain spec conform for the foreseeable future.

closing as I think we've said all we can for now, thanks for the discussion 馃憤

FYI - another possibility...
if your willing to have your css hosted on external resource/location...

  .getElementsByTagName("head")[0]
  .insertAdjacentHTML(
    "beforeend",
    '<link rel="stylesheet" href="https://path/to/some/cdn/or/location/with/styles.css" />'
  );

I was worried for a long time, and finally decided to embrace styled-components

I was worried for a long time, and finally decided to embrace styled-components

Doesn't this add some weight to your library? Styled-components seems a bit clumsy to me, and it also assumes that the consumer of the library is going to use styled-components, doesn't it?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sptimer picture sptimer  路  4Comments

pkrawc picture pkrawc  路  4Comments

bitttttten picture bitttttten  路  4Comments

cowboyd picture cowboyd  路  3Comments

SleeplessByte picture SleeplessByte  路  3Comments