facebook / stylex

StyleX is the styling system for ambitious user interfaces.
https://stylexjs.com
MIT License
8.22k stars 303 forks source link

feat: Using CSS data urls for bundling #513

Open nmn opened 3 months ago

nmn commented 3 months ago

Resolving #297

Idea

The idea is that the Babel plugin should be able to generate import statements that import CSS as data URLs. After this, bundlers should be able to generate CSS bundles to include this CSS and a PostCSS/LightningCSS plugin can post-process the CSS file after the fact.

Challenge

I am unable to figure out a valid format for CSS data URL that can be put into a JS import statement.

I tried to come up with the simplest possible example of trying to inject body{background:pink} and tried the following import statements:

import 'data:text/css;charset=utf-8,body{background:pink}';
import 'data:text/css;charset=utf-8,body{background:pink}';
import 'css?data:text/css;charset=utf-8,body{background:pink}';
import '?css:data:text/css;charset=utf-8,body{background:pink}';
import 'css-loader?data:text/css;charset=utf-8,body{background:pink}';
import 'data:text/css;charset=utf-8,body{background:pink}?css';
import 'data:text/css;charset=utf-8,body{background:pink}?css-loader';

import 'data:text/css;charset=utf-8,body{background:pink}';
import 'data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D';
import 'css?data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D';
import '?css:data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D';
import 'css-loader?data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D';
import 'data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D?css';
import 'data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D?css-loader';

import 'data:text/css,body{background:pink}';
import 'data:text/css,body%7Bbackground%3Apink%7D';
import 'css?data:text/css,body%7Bbackground%3Apink%7D';
import '?css:data:text/css,body%7Bbackground%3Apink%7D';
import 'css-loader?data:text/css,body%7Bbackground%3Apink%7D';
import 'data:text/css,body%7Bbackground%3Apink%7D?css';
import 'data:text/css,body%7Bbackground%3Apink%7D?css-loader';

import 'style-loader?data:text/css;charset=utf-8,body{background:pink}';
import 'style-loader?data:text/css;charset=utf-8,body%7Bbackground%3Apink%7D';
import 'style-loader?data:text/css,body%7Bbackground%3Apink%7D';

I wasn't able to get any of them work in a fresh NextJS example. Webpack did not understand any of these imports.

I tried the same in Vite with similar results.

Is there a particular way to make bundlers bundle CSS provided this way?

Is this approach even feasible? I'm putting up this PR in case someone has further insight here.

We are independently working on a CLI to work around bundlers entirely in the meantime.

github-actions[bot] commented 3 months ago

compressed-size: runtime library

Size change: 0.00 kB Total size: 2.52 kB

View unchanged | Filename: gzip (minify) | kB size | kB change | % change | | :--- | :--- | :--- | :--- | | `./packages/stylex/lib/stylex.js` | **1.04** (3.22) | **0.00** (0.00) | **0.0%** (0.0%) | | `./packages/stylex/lib/StyleXSheet.js` | **1.48** (3.75) | **0.00** (0.00) | **0.0%** (0.0%) |
github-actions[bot] commented 3 months ago

compressed-size: e2e bundles

Size change: 0.00 kB Total size: 1128.55 kB

View unchanged | Filename: gzip (minify) | kB size | kB change | % change | | :--- | :--- | :--- | :--- | | `./apps/rollup-example/.build/bundle.js` | **1005.20** (10185.36) | **0.00** (0.00) | **0.0%** (0.0%) | | `./apps/rollup-example/.build/stylex.css` | **123.34** (773.82) | **0.00** (0.00) | **0.0%** (0.0%) |