Repository navigation
[backend] Write StyleX theme definitions to theme files - #638
purefunctor wants to merge 3 commits into
Conversation
StyleX resolves imported defineVars, defineConsts, and defineMarker values only through imports of the defining module's theme file. Validation already proves which imported values StyleX evaluates statically; keep that set on the functional module so code generation can choose their import paths. Amp-Thread-ID: https://ampcode.com/threads/T-01a118ca-d95d-702f-85cb-95686f6ce5ed Co-authored-by: Amp <amp@ampcode.com>
StyleX accepts defineVars, defineConsts, and defineMarker only in files named *.stylex.js, so projects previously had to mark every generated index.js as a theme file through unstable_moduleResolution.themeFileExtension. Write a module's exported theme definitions to index.stylex.js, which index.js re-exports. Same-module values that the definitions read are copied into the theme file: StyleX evaluates every import of a theme file as a theme value, so importing them from it would break the definitions. Modules import statically evaluated theme values from the defining module's theme file and everything else from its index.js. With @stylexjs/unplugin, Iris output now needs no module resolution options. Amp-Thread-ID: https://ampcode.com/threads/T-01a118ca-d95d-702f-85cb-95686f6ce5ed Co-authored-by: Amp <amp@ampcode.com>
`iris watch query javascript` shows what the StyleX plugin receives, which now includes a module's theme file. Label both files when the module has one. Amp-Thread-ID: https://ampcode.com/threads/T-01a118ca-d95d-702f-85cb-95686f6ce5ed Co-authored-by: Amp <amp@ampcode.com>
Compatibility regression reportPackage set ✅ The candidate introduces no compatibility errors.
Introduced errorsNone. Fixed errors (0)None. Warning changes (0 introduced, 0 fixed)Introduced None. Fixed None. Candidate errors (0)None. Candidate warnings (36)
|
|
Reviewed against AGENTS.md. I found no issues to raise. The fix sits in the layers that own it. Functional validation already proves which imported values StyleX evaluates statically, and it now records them as
So the theme file only ever imports theme values and copies static same-module helpers. Every path that writes JavaScript output writes the extra file: On tests: the fixture changes in Checks run locally:
I did not run the e2e suite locally; CI covers it. |
Writes a module's exported StyleX theme definitions to
output/<Module>/index.stylex.js. Iris output now builds with@stylexjs/unpluginwithout the manualunstable_moduleResolutionsetting:Previously the plugin accepted
defineVars,defineConsts, anddefineMarkeronly when every generatedindex.jswas marked as a theme file throughthemeFileExtension: "index".This breaks projects that still set
themeFileExtension: "index": that setting no longer matches the generated files, so they should remove it. Variable and class hashes also change, because StyleX hashes the file path.Amp thread: https://ampcode.com/threads/T-01a118ca-d95d-702f-85cb-95686f6ce5ed
Design
StyleX 0.19.0 checks file names in two places:
defineVars,defineConsts, anddefineMarkerin files named*.stylex.js.@stylexjs/unplugindefaults to{ type: "commonJS", rootDir: process.cwd() }, so it needs no other setting.index.jsimports them from./index.stylex.jsand re-exports them, so imports ofindex.jskeep working and the re-exported object is the same one.gap = "21px"indefineConsts { gap }, are rendered again in the theme file. StyleX treats every value imported from a theme file as a theme variable, so importing a helper back intoindex.jsfails with "A style value can only contain an array, string or number". These values are plain static data, so copying them is safe. This also means the theme file never imports its ownindex.js, so the split adds no import cycles.../<Module>/index.stylex.js; everything else, such as adefaultMarkerused only inprops, keeps../<Module>/index.js. Choosing paths from the generator's own list of StyleX references would import runtime-only values from a file that does not export them.createTheme,keyframes,positionTry, andviewTransitionClassstay inindex.js. StyleX hashes them without a theme file.iris buildand the fixture harness write the extra file. Incremental builds delete a staleindex.stylex.jsonce a module stops defining theme values.iris watch query javascriptshows both files, each under a filename comment.Tests
{ type: "commonJS", rootDir }to@stylexjs/babel-plugin0.19.0 and also transformsTokens/index.stylex.js. It checks:MaindefineConstsand a same-modulecreate(margin:21px)style_x_cross_module_valuesnow also covers a copied helper and a runtime-only import from a theme module. Goldens for the other theme fixtures gainindex.stylex.js.just t compilerandjust t lsppass with no pending snapshots. All 63 tests incargo nextest run -p tests-e2epass.stylex.vite({ useCSSLayers: true })produced the expected variable, marker, and helper rules. That check is not part of the test suite.Follow-ups
unstable_moduleResolutionfrom itsastro.config.mjsafter a release.positionTryemits a malformed@position-tryblock that lightningcss rejects in real Vite builds. The Babel-only e2e test does not parse that CSS.