Handle CSS files
IvanSanchez opened this issue · 4 comments
Some NPM packages specify CSS files in them, e.g.: https://github.com/Leaflet/Leaflet/blob/master/package.json#L23 and https://github.com/twbs/bootstrap/blob/master/package.json#L20
It would be desirable that rollup-plugin-npm would load these files by means of rollup-plugin-postcss.
I'm not sure I understand how this would work? If you did...
import 'leaflet';
...then Rollup wouldn't be able to know that you wanted to import leaflet/dist/leaflet.css
– it would assume you wanted the JavaScript. Whereas if it was a CSS import...
@import 'leaflet';
...then surely it's the responsibility of a PostCSS plugin to locate the file and include it, rather than rollup-plugin-npm?
Off the top of my head, this should work, if rollup-plugin-postcss is present:
import 'leaflet/dist/leaflet.css';
Or have I misunderstood?
Or have I misunderstood?
No, no. You have a good point and I didn't explain myself very well.
The use case here is bundling libraries. e.g. I want to bundle up leaflet, bootstrap, jquery and turfjs - and I don't want to care about the name of the entry point for the javascript (main
or jsnext:main
or whatever), and I don't want to care about the entry point for the CSS, or for whatever else is needed to make the code work in a single bundle.
So right now, when one writes in javascript
import 'leaflet'
...then it is my understanding that rollup-plugin-npm reads the package.json
file and somehow translates that into...
import 'node_modules/leaflet/dist/leaflet.js'
...and what I would like instead is detect rollup-plugin-postcss (or make an option to enable it) so it would do this instead:
import 'node_modules/leaflet/dist/leaflet.js'
import 'node_modules/leaflet/dist/leaflet.css'
And then, with some postcss-js magic, bundle the CSS inside the JS.
I can currently achieve this via a crazy set of gobblejs transforms, but it feels way too clunky. Somehow I think that rollup-plugin-npm is the right place to bundle up the JS and CSS of a node module, and not handle the CSS files of node modules in a separate stage.
Ah, interesting. Here's a sketch for an approach that seems like it could work:
- Plugins like rollup-plugin-postcss include a
meta
property, likemeta: { css: true }
- rollup-plugin-npm includes an
option
hook that scans each item inoptions.plugins
to see if any has ameta.css
property - If there is such a plugin, rollup-plugin-npm looks for a
pkg.style
at the same time as it's looking formain
orjsnext:main
. If it finds one, instead of resolving to the main file, it resolves to a virtual module ID - rollup-plugin-npm adds a
load
hook that, given a virtual module ID like__npm:leaflet
returns a module importing bothleaflet/dist/leaflet-src.js
andleaflet/dist/leaflet.css
- From there, whatever CSS-aware plugin exists (doesn't have to be PostCSS, as long as it exposes
meta.css
) takes over
That seems doable. It should probably be hidden behind an option though.
The tricky part is what to do about relative paths, such as images – does PostCSS have some magic for ensuring these are correct? Or maybe inlining as data URIs?
Sounds sane and doable. Me like!
The tricky part is what to do about relative paths, such as images – does PostCSS have some magic for ensuring these are correct? Or maybe inlining as data URIs?
Apparently there is https://github.com/assetsjs/postcss-assets for just that.
Given the amount of hacks for images and CSS paths (see this if you dare), I'd expect developers to be able to pop the images in the correct directories. IMHO, some use cases call for lazy loading of images whose URLs are defined in the CSS, other use cases call for preloading everything.
Maybe there could be more properties in a package.json
file pointing to image and/or font files, and copy them around, but that's gobblejs territory, not rollup territory.