@@ -5,34 +5,47 @@ import { fileURLToPath } from 'url';
55const require = createRequire ( import . meta. url ) ;
66const __dirname = dirname ( fileURLToPath ( import . meta. url ) ) ;
77
8- // StyleX CSS extraction. The `@stylexjs/postcss-plugin` scans the Mosaic source, runs the
9- // StyleX babel transform itself, and replaces the `@stylex;` directive in `globals.css` with
10- // the generated CSS (token `:root` defaults + atoms). This is the CSS half of the setup; the
11- // JS half is the unplugin in `next.config.mjs`. Both must use the SAME StyleX babel version
12- // and options (`dev`, `rootDir`) so the atom class hashes line up.
138const uiRoot = resolve ( __dirname , '../ui' ) ;
9+ const isDev = process . env . NODE_ENV !== 'production' ;
1410
15- export default {
16- plugins : {
17- '@stylexjs/postcss-plugin' : {
18- useCSSLayers : true ,
19- babelConfig : {
20- babelrc : false ,
21- configFile : false ,
22- presets : [ require ( '@babel/preset-typescript' ) ] ,
23- plugins : [
24- require ( '@babel/plugin-syntax-jsx' ) ,
25- [
26- require ( '@stylexjs/babel-plugin' ) ,
27- {
28- dev : process . env . NODE_ENV !== 'production' ,
29- runtimeInjection : false ,
30- unstable_moduleResolution : { type : 'commonJS' , rootDir : uiRoot } ,
31- } ,
32- ] ,
11+ // StyleX CSS. `@stylexjs/postcss-plugin` scans the Mosaic source, runs the StyleX babel
12+ // transform, and replaces the `@stylex;` directive in `globals.css` with the generated CSS:
13+ // the token `:root { --cl-* }` defaults *and* the atoms. This runs in BOTH dev and prod
14+ // because it is the only thing that emits the `:root` token defaults — StyleX's `defineVars`
15+ // is compile-time-only (its runtime export throws), so `runtimeInjection` alone leaves every
16+ // `var(--cl-*)` unresolved (unstyled). Its babel `dev`/`rootDir` must match the unplugin in
17+ // `next.config.mjs` so atom hashes line up.
18+ //
19+ // In dev this sheet goes stale on `.styles.ts` edits (Next won't re-run the `globals.css`
20+ // PostCSS pass for files outside the CSS import graph), but that's fine: the unplugin's
21+ // `runtimeInjection` (see `next.config.mjs`) injects the *fresh* atom at runtime under a new
22+ // content hash, which HMR tracks. The stale extracted atom is dead CSS; the `:root` token
23+ // defaults never change mid-session, so they stay correct.
24+ const stylexExtraction = {
25+ '@stylexjs/postcss-plugin' : {
26+ useCSSLayers : true ,
27+ babelConfig : {
28+ babelrc : false ,
29+ configFile : false ,
30+ presets : [ require ( '@babel/preset-typescript' ) ] ,
31+ plugins : [
32+ require ( '@babel/plugin-syntax-jsx' ) ,
33+ [
34+ require ( '@stylexjs/babel-plugin' ) ,
35+ {
36+ dev : isDev ,
37+ runtimeInjection : false ,
38+ unstable_moduleResolution : { type : 'commonJS' , rootDir : uiRoot } ,
39+ } ,
3340 ] ,
34- } ,
41+ ] ,
3542 } ,
43+ } ,
44+ } ;
45+
46+ export default {
47+ plugins : {
48+ ...stylexExtraction ,
3649 '@tailwindcss/postcss' : { } ,
3750 } ,
3851} ;
0 commit comments