From de6986677963dfeca2a9817e117fb723b514f745 Mon Sep 17 00:00:00 2001 From: Melissa Liu Date: Mon, 1 Dec 2025 05:21:34 -0500 Subject: [PATCH] [babel-plugin] optimize and inline variables in processStylexRules --- package-lock.json | 131 +++++++++-- .../__tests__/transform-process-test.js | 204 +++++++++++++----- .../@stylexjs/babel-plugin/src/index.d.ts | 1 + packages/@stylexjs/babel-plugin/src/index.js | 144 ++++++++++++- 4 files changed, 412 insertions(+), 68 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d0073286..cb0bf36e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,6 +60,7 @@ "integrity": "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -79,6 +80,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -586,6 +588,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -867,6 +870,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -879,6 +883,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -970,6 +975,7 @@ "version": "19.2.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1230,6 +1236,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -1273,6 +1280,7 @@ "examples/example-react-router/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -1280,6 +1288,7 @@ "examples/example-react-router/node_modules/react-dom": { "version": "19.2.0", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -1367,6 +1376,7 @@ "version": "7.2.4", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -1463,6 +1473,7 @@ "examples/example-redwoodsdk/node_modules/@cloudflare/vite-plugin": { "version": "1.15.2", "license": "MIT", + "peer": true, "dependencies": { "@cloudflare/unenv-preset": "2.7.11", "@remix-run/node-fetch-server": "^0.8.0", @@ -1540,6 +1551,7 @@ "version": "19.2.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -1857,6 +1869,7 @@ "examples/example-redwoodsdk/node_modules/picomatch": { "version": "4.0.3", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -1867,6 +1880,7 @@ "examples/example-redwoodsdk/node_modules/react": { "version": "19.3.0-canary-561ee24d-20251101", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -1874,6 +1888,7 @@ "examples/example-redwoodsdk/node_modules/react-dom": { "version": "19.3.0-canary-561ee24d-20251101", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "0.28.0-canary-561ee24d-20251101" }, @@ -1888,6 +1903,7 @@ "examples/example-redwoodsdk/node_modules/react-server-dom-webpack": { "version": "19.3.0-canary-561ee24d-20251101", "license": "MIT", + "peer": true, "dependencies": { "acorn-loose": "^8.3.0", "neo-async": "^2.6.1", @@ -2003,6 +2019,7 @@ "examples/example-redwoodsdk/node_modules/rwsdk/node_modules/@types/react": { "version": "19.1.17", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.0.2" } @@ -2144,6 +2161,7 @@ "examples/example-redwoodsdk/node_modules/vite": { "version": "7.2.4", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -2266,6 +2284,7 @@ "examples/example-rollup/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2335,6 +2354,7 @@ "examples/example-rspack/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -2551,6 +2571,7 @@ "version": "8.44.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.44.0", "@typescript-eslint/types": "8.44.0", @@ -2772,6 +2793,7 @@ "version": "9.36.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -2873,6 +2895,7 @@ "version": "3.0.3", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -2981,6 +3004,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3089,6 +3113,7 @@ "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -3395,6 +3420,7 @@ "version": "19.2.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3419,6 +3445,7 @@ "version": "9.39.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3580,6 +3607,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3590,6 +3618,7 @@ "examples/example-vite-react/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -3712,6 +3741,7 @@ "version": "19.2.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -3801,6 +3831,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3811,6 +3842,7 @@ "examples/example-vite-rsc/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -3818,6 +3850,7 @@ "examples/example-vite-rsc/node_modules/react-dom": { "version": "19.2.0", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -3843,6 +3876,7 @@ "version": "7.1.12", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -3960,6 +3994,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -3970,6 +4005,7 @@ "examples/example-vite/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4002,6 +4038,7 @@ "version": "7.2.4", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -4098,6 +4135,7 @@ "version": "19.2.6", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -4168,6 +4206,7 @@ "examples/example-waku/node_modules/picomatch": { "version": "4.0.3", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -4178,6 +4217,7 @@ "examples/example-waku/node_modules/react": { "version": "19.2.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4185,6 +4225,7 @@ "examples/example-waku/node_modules/react-dom": { "version": "19.2.0", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -4202,6 +4243,7 @@ "examples/example-waku/node_modules/react-server-dom-webpack": { "version": "19.2.0", "license": "MIT", + "peer": true, "dependencies": { "acorn-loose": "^8.3.0", "neo-async": "^2.6.1", @@ -4223,6 +4265,7 @@ "examples/example-waku/node_modules/vite": { "version": "7.2.2", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -4384,6 +4427,7 @@ "version": "8.17.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -4546,6 +4590,7 @@ "examples/example-webpack/node_modules/react": { "version": "19.1.1", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -4864,6 +4909,7 @@ "node_modules/@algolia/client-search": { "version": "5.34.0", "license": "MIT", + "peer": true, "dependencies": { "@algolia/client-common": "5.34.0", "@algolia/requester-browser-xhr": "5.34.0", @@ -5172,6 +5218,7 @@ "node_modules/@babel/core": { "version": "7.28.5", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -7167,7 +7214,8 @@ "node_modules/@cloudflare/workers-types": { "version": "4.20251121.0", "devOptional": true, - "license": "MIT OR Apache-2.0" + "license": "MIT OR Apache-2.0", + "peer": true }, "node_modules/@colors/colors": { "version": "1.5.0", @@ -7275,6 +7323,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" }, @@ -7295,6 +7344,7 @@ } ], "license": "MIT", + "peer": true, "engines": { "node": ">=18" } @@ -8579,6 +8629,7 @@ "node_modules/@fortawesome/fontawesome-svg-core": { "version": "6.7.2", "license": "MIT", + "peer": true, "dependencies": { "@fortawesome/fontawesome-common-types": "6.7.2" }, @@ -9640,6 +9691,7 @@ "node_modules/@mdx-js/mdx/node_modules/@babel/core": { "version": "7.12.9", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", @@ -10096,6 +10148,7 @@ "version": "3.6.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@octokit/auth-token": "^2.4.4", "@octokit/graphql": "^4.5.8", @@ -10292,6 +10345,7 @@ "version": "8.17.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -10627,6 +10681,7 @@ "version": "5.2.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^2.0.2", @@ -10964,6 +11019,7 @@ "version": "1.6.4", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@module-federation/runtime-tools": "0.21.4", "@rspack/binding": "1.6.4", @@ -11019,6 +11075,7 @@ "version": "8.17.1", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -11274,6 +11331,7 @@ "version": "8.13.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", @@ -11903,6 +11961,7 @@ "node_modules/@svgr/core": { "version": "6.5.1", "license": "MIT", + "peer": true, "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -12580,6 +12639,7 @@ "node_modules/@types/react": { "version": "18.3.23", "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -13488,6 +13548,7 @@ "version": "3.2.4", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@testing-library/dom": "^10.4.0", "@testing-library/user-event": "^14.6.1", @@ -13683,7 +13744,6 @@ "version": "3.2.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", @@ -14019,6 +14079,7 @@ "node_modules/acorn": { "version": "8.15.0", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -14091,6 +14152,7 @@ "node_modules/ajv": { "version": "6.12.6", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14145,6 +14207,7 @@ "node_modules/algoliasearch": { "version": "4.25.2", "license": "MIT", + "peer": true, "dependencies": { "@algolia/cache-browser-local-storage": "4.25.2", "@algolia/cache-common": "4.25.2", @@ -14602,6 +14665,7 @@ "node_modules/astring": { "version": "1.9.0", "license": "MIT", + "peer": true, "bin": { "astring": "bin/astring" } @@ -15274,6 +15338,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001726", "electron-to-chromium": "^1.5.173", @@ -15377,7 +15442,6 @@ "version": "6.7.14", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=8" } @@ -16032,7 +16096,8 @@ }, "node_modules/codemirror": { "version": "5.65.19", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/collapse-white-space": { "version": "1.0.6", @@ -16312,6 +16377,7 @@ "node_modules/copy-webpack-plugin/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -16601,6 +16667,7 @@ "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -17462,7 +17529,8 @@ }, "node_modules/devtools-protocol": { "version": "0.0.1495869", - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "peer": true }, "node_modules/dir-glob": { "version": "3.0.1", @@ -18080,6 +18148,7 @@ "node_modules/eslint": { "version": "8.57.1", "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -18326,6 +18395,7 @@ "version": "2.32.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -18377,6 +18447,7 @@ "version": "6.10.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", @@ -18405,6 +18476,7 @@ "version": "7.37.5", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -18436,6 +18508,7 @@ "version": "4.6.2", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -19581,6 +19654,7 @@ "node_modules/flow-api-translator/node_modules/typescript": { "version": "5.3.2", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -21138,6 +21212,7 @@ "node_modules/hermes-eslint": { "version": "0.32.1", "license": "MIT", + "peer": true, "dependencies": { "esrecurse": "^4.3.0", "hermes-estree": "0.32.1", @@ -21252,6 +21327,7 @@ "node_modules/hono": { "version": "4.10.6", "license": "MIT", + "peer": true, "engines": { "node": ">=16.9.0" } @@ -23781,6 +23857,7 @@ "version": "26.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", @@ -23913,6 +23990,7 @@ "node_modules/kysely": { "version": "0.28.8", "license": "MIT", + "peer": true, "engines": { "node": ">=20.0.0" } @@ -23979,6 +24057,7 @@ "node_modules/lightningcss": { "version": "1.30.2", "license": "MPL-2.0", + "peer": true, "dependencies": { "detect-libc": "^2.0.3" }, @@ -26025,6 +26104,7 @@ "node_modules/mini-css-extract-plugin/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -27231,6 +27311,7 @@ "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", "dev": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "playwright-core": "1.57.0" }, @@ -27293,6 +27374,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -27700,6 +27782,7 @@ "version": "7.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -27901,6 +27984,7 @@ "node_modules/postcss-selector-parser": { "version": "6.1.2", "license": "MIT", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -27980,6 +28064,7 @@ "node_modules/prettier": { "version": "3.5.3", "license": "MIT", + "peer": true, "bin": { "prettier": "bin/prettier.cjs" }, @@ -27994,6 +28079,7 @@ "version": "0.32.0", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "prettier": "^3.0.0" } @@ -28441,6 +28527,7 @@ "node_modules/react": { "version": "17.0.2", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -28568,6 +28655,7 @@ "node_modules/react-dom": { "version": "17.0.2", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -28627,6 +28715,7 @@ "name": "@docusaurus/react-loadable", "version": "5.5.2", "license": "MIT", + "peer": true, "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" @@ -28652,6 +28741,7 @@ "node_modules/react-refresh": { "version": "0.17.0", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -28659,6 +28749,7 @@ "node_modules/react-router": { "version": "5.3.4", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -29511,6 +29602,7 @@ "node_modules/remark-mdx/node_modules/@babel/core": { "version": "7.12.9", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/generator": "^7.12.5", @@ -30141,6 +30233,7 @@ "node_modules/rollup": { "version": "4.45.1", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -31299,6 +31392,7 @@ "version": "9.1.7", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@storybook/global": "^5.0.0", "@testing-library/jest-dom": "^6.6.3", @@ -32232,6 +32326,7 @@ "node_modules/terser-webpack-plugin/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -32444,6 +32539,7 @@ "node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.3", "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -32455,7 +32551,6 @@ "version": "1.1.1", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": "^18.0.0 || >=20.0.0" } @@ -32705,7 +32800,8 @@ }, "node_modules/tslib": { "version": "2.8.1", - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/turbo-stream": { "version": "3.1.0", @@ -32835,6 +32931,7 @@ "node_modules/typescript": { "version": "5.9.3", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -32902,6 +32999,7 @@ "version": "8.46.3", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -33207,6 +33305,7 @@ "node_modules/unenv": { "version": "2.0.0-rc.24", "license": "MIT", + "peer": true, "dependencies": { "pathe": "^2.0.3" } @@ -33433,7 +33532,6 @@ "node_modules/unplugin": { "version": "2.3.11", "license": "MIT", - "peer": true, "dependencies": { "@jridgewell/remapping": "^2.3.5", "acorn": "^8.15.0", @@ -33447,7 +33545,6 @@ "node_modules/unplugin/node_modules/picomatch": { "version": "4.0.3", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -33977,7 +34074,6 @@ "version": "3.2.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", @@ -33999,7 +34095,6 @@ "version": "6.5.0", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.0.0" }, @@ -34028,7 +34123,6 @@ "version": "7.1.6", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", @@ -34233,7 +34327,6 @@ "version": "3.2.4", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", @@ -34259,7 +34352,6 @@ "version": "3.0.3", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/estree": "^1.0.0" } @@ -34268,7 +34360,6 @@ "version": "6.5.0", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12.0.0" }, @@ -34451,6 +34542,7 @@ "node_modules/webpack": { "version": "5.101.3", "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -34676,6 +34768,7 @@ "node_modules/webpack-dev-middleware/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -34785,6 +34878,7 @@ "node_modules/webpack-dev-server/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -34884,6 +34978,7 @@ "node_modules/webpack/node_modules/ajv": { "version": "8.17.1", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -35149,6 +35244,7 @@ "version": "1.20251118.0", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "bin": { "workerd": "bin/workerd" }, @@ -35166,6 +35262,7 @@ "node_modules/wrangler": { "version": "4.50.0", "license": "MIT OR Apache-2.0", + "peer": true, "dependencies": { "@cloudflare/kv-asset-handler": "0.4.0", "@cloudflare/unenv-preset": "2.7.11", @@ -35839,6 +35936,7 @@ "version": "2.3.1", "devOptional": true, "license": "ISC", + "peer": true, "engines": { "node": ">= 14" } @@ -36111,6 +36209,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -36222,6 +36321,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -36330,6 +36430,7 @@ "version": "4.0.3", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, diff --git a/packages/@stylexjs/babel-plugin/__tests__/transform-process-test.js b/packages/@stylexjs/babel-plugin/__tests__/transform-process-test.js index 1cadd696c..2446e3389 100644 --- a/packages/@stylexjs/babel-plugin/__tests__/transform-process-test.js +++ b/packages/@stylexjs/babel-plugin/__tests__/transform-process-test.js @@ -182,13 +182,9 @@ describe('@stylexjs/babel-plugin', () => { useLayers: false, enableLTRRTLComments: false, }), - ).toMatchInlineSnapshot(` - ":root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} - @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}}" - `); + ).toMatchInlineSnapshot( + '"@supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}}"', + ); }); test('all rules (useLayers:false)', () => { @@ -255,25 +251,21 @@ describe('@stylexjs/babel-plugin', () => { ).toMatchInlineSnapshot(` "@property --x-color { syntax: "*"; inherits: false;} @keyframes x35atj5-B{0%{box-shadow:1px 2px 3px 4px red;color:yellow;}100%{box-shadow:10px 20px 30px 40px green;color:var(--orange-theme-color);}} - :root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x6xqkwy.x6xqkwy, .x6xqkwy.x6xqkwy:root{--blue-xpqh4lw:lightblue;} .x57uvma.x57uvma, .x57uvma.x57uvma:root{--large-x1ec7iuc:20px;--medium-xypjos2:10px;--small-x19twipt:5px;} .--orange-theme-color-xufgesz{--orange-theme-color:red} .margin-xymmreb:not(#\\#){margin:10px 20px} - .padding-xss17vw:not(#\\#){padding:var(--large-x1ec7iuc)} + .padding-xss17vw:not(#\\#){padding:8px} .borderColor-x1bg2uv5:not(#\\#):not(#\\#){border-color:green} - @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c:not(#\\#):not(#\\#){border-color:var(--blue-xpqh4lw)}} + @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c:not(#\\#):not(#\\#){border-color:blue}} @media (max-width: 500px){@media (max-width: 1000px){.borderColor-xqiy1ys.borderColor-xqiy1ys.borderColor-xqiy1ys:not(#\\#):not(#\\#){border-color:yellow}}} .animationName-x13ah0pd:not(#\\#):not(#\\#):not(#\\#){animation-name:x35atj5-B} .backgroundColor-xrkmrrc:not(#\\#):not(#\\#):not(#\\#){background-color:red} .color-x14rh7hd:not(#\\#):not(#\\#):not(#\\#){color:var(--x-color)} html:not([dir='rtl']) .float-x1kmio9f:not(#\\#):not(#\\#):not(#\\#){float:left} html[dir='rtl'] .float-x1kmio9f:not(#\\#):not(#\\#):not(#\\#){float:right} - .outlineColor-x184ctg8:not(#\\#):not(#\\#):not(#\\#){outline-color:var(--colorTokens-xkxfyv)} + .outlineColor-x184ctg8:not(#\\#):not(#\\#):not(#\\#){outline-color:lightblue} .textShadow-x1skrh0i:not(#\\#):not(#\\#):not(#\\#){text-shadow:1px 2px 3px 4px red} .backgroundColor-xfy810d.backgroundColor-xfy810d:where(.x-default-marker:focus *):not(#\\#):not(#\\#):not(#\\#){background-color:green} .backgroundColor-xbrh7vm:hover:not(#\\#):not(#\\#):not(#\\#){background-color:blue} @@ -350,21 +342,17 @@ describe('@stylexjs/babel-plugin', () => { @layer priority1, priority2, priority3, priority4; @property --x-color { syntax: "*"; inherits: false;} @keyframes x35atj5-B{0%{box-shadow:1px 2px 3px 4px red;color:yellow;}100%{box-shadow:10px 20px 30px 40px green;color:var(--orange-theme-color);}} - :root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x6xqkwy.x6xqkwy, .x6xqkwy.x6xqkwy:root{--blue-xpqh4lw:lightblue;} .x57uvma.x57uvma, .x57uvma.x57uvma:root{--large-x1ec7iuc:20px;--medium-xypjos2:10px;--small-x19twipt:5px;} .--orange-theme-color-xufgesz{--orange-theme-color:red} @layer priority2{ .margin-xymmreb{margin:10px 20px} - .padding-xss17vw{padding:var(--large-x1ec7iuc)} + .padding-xss17vw{padding:8px} } @layer priority3{ .borderColor-x1bg2uv5{border-color:green} - @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c{border-color:var(--blue-xpqh4lw)}} + @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c{border-color:blue}} @media (max-width: 500px){@media (max-width: 1000px){.borderColor-xqiy1ys.borderColor-xqiy1ys.borderColor-xqiy1ys{border-color:yellow}}} } @layer priority4{ @@ -373,7 +361,7 @@ describe('@stylexjs/babel-plugin', () => { .color-x14rh7hd{color:var(--x-color)} html:not([dir='rtl']) .float-x1kmio9f{float:left} html[dir='rtl'] .float-x1kmio9f{float:right} - .outlineColor-x184ctg8{outline-color:var(--colorTokens-xkxfyv)} + .outlineColor-x184ctg8{outline-color:lightblue} .textShadow-x1skrh0i{text-shadow:1px 2px 3px 4px red} .backgroundColor-xfy810d.backgroundColor-xfy810d:where(.x-default-marker:focus *){background-color:green} .backgroundColor-xbrh7vm:hover{background-color:blue} @@ -448,25 +436,21 @@ describe('@stylexjs/babel-plugin', () => { ).toMatchInlineSnapshot(` "@property --x-color { syntax: "*"; inherits: false;} @keyframes x35atj5-B{0%{box-shadow:1px 2px 3px 4px red;color:yellow;}100%{box-shadow:10px 20px 30px 40px green;color:var(--orange-theme-color);}} - :root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x6xqkwy.x6xqkwy, .x6xqkwy.x6xqkwy:root{--blue-xpqh4lw:lightblue;} .x57uvma.x57uvma, .x57uvma.x57uvma:root{--large-x1ec7iuc:20px;--medium-xypjos2:10px;--small-x19twipt:5px;} .--orange-theme-color-xufgesz{--orange-theme-color:red} .margin-xymmreb{margin:10px 20px} - .padding-xss17vw{padding:var(--large-x1ec7iuc)} + .padding-xss17vw{padding:8px} .borderColor-x1bg2uv5{border-color:green} - @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c{border-color:var(--blue-xpqh4lw)}} + @media (max-width: 1000px){.borderColor-x5ugf7c.borderColor-x5ugf7c{border-color:blue}} @media (max-width: 500px){@media (max-width: 1000px){.borderColor-xqiy1ys.borderColor-xqiy1ys.borderColor-xqiy1ys{border-color:yellow}}} .animationName-x13ah0pd{animation-name:x35atj5-B} .backgroundColor-xrkmrrc{background-color:red} .color-x14rh7hd{color:var(--x-color)} html:not([dir='rtl']) .float-x1kmio9f{float:left} html[dir='rtl'] .float-x1kmio9f{float:right} - .outlineColor-x184ctg8{outline-color:var(--colorTokens-xkxfyv)} + .outlineColor-x184ctg8{outline-color:lightblue} .textShadow-x1skrh0i{text-shadow:1px 2px 3px 4px red} .backgroundColor-xfy810d.backgroundColor-xfy810d:where(.x-default-marker:focus *){background-color:green} .backgroundColor-xbrh7vm:hover{background-color:blue} @@ -545,10 +529,6 @@ describe('@stylexjs/babel-plugin', () => { --stylex-logical-start: right; --stylex-logical-end: left; } - :root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} .float-xj87blo:not(#\\#){float:var(--stylex-logical-start)} /* @ltr begin */.marginInlineStart-xqsn43r:not(#\\#){margin-left:20px}/* @ltr end */ @@ -590,11 +570,7 @@ describe('@stylexjs/babel-plugin', () => { enableLTRRTLComments: false, }), ).toMatchInlineSnapshot(` - ":root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} - :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} - @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + "@supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x6xqkwy.x6xqkwy, .x6xqkwy.x6xqkwy:root{--blue-xpqh4lw:lightblue;} .x57uvma.x57uvma, .x57uvma.x57uvma:root{--large-x1ec7iuc:20px;--medium-xypjos2:10px;--small-x19twipt:5px;}" `); @@ -643,25 +619,21 @@ describe('@stylexjs/babel-plugin', () => { ).toMatchInlineSnapshot(` "@property --x-color { syntax: "*"; inherits: false;} @keyframes x35atj5-B{0%{box-shadow:1px 2px 3px 4px red;color:yellow;}100%{box-shadow:10px 20px 30px 40px green;color:var(--orange-theme-color);}} - :root, .xbiwvf9{--x19twipt:2px;--xypjos2:4px;--x1ec7iuc:8px;} - :root, .xsg933n{--xpqh4lw:blue;--x8nt2k2:10px;--xkxfyv:red;} - @media (min-width: 600px){:root, .xsg933n{--x8nt2k2:20px;}} - @media (prefers-color-scheme: dark){:root, .xsg933n{--xkxfyv:lightblue;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x4hn0rr.x4hn0rr, .x4hn0rr.x4hn0rr:root{--x1ec7iuc:20px;--xypjos2:10px;--x19twipt:5px;} .x1coplze.x1coplze, .x1coplze.x1coplze:root{--xpqh4lw:lightblue;} .xufgesz{--orange-theme-color:red} .xymmreb{margin:10px 20px} - .x1s2izit{padding:var(--x1ec7iuc)} + .x1s2izit{padding:8px} .x1bg2uv5{border-color:green} - @media (max-width: 1000px){.xio2edn.xio2edn{border-color:var(--xpqh4lw)}} + @media (max-width: 1000px){.xio2edn.xio2edn{border-color:blue}} @media (max-width: 500px){@media (max-width: 1000px){.xqiy1ys.xqiy1ys.xqiy1ys{border-color:yellow}}} .x13ah0pd{animation-name:x35atj5-B} .xrkmrrc{background-color:red} .x14rh7hd{color:var(--x-color)} /* @ltr begin */.x1kmio9f{float:left}/* @ltr end */ /* @rtl begin */.x1kmio9f{float:right}/* @rtl end */ - .x18abd1y{outline-color:var(--xkxfyv)} + .x18abd1y{outline-color:lightblue} .x1skrh0i{text-shadow:1px 2px 3px 4px red} .xfy810d.xfy810d:where(.x-default-marker:focus *){background-color:green} .xbrh7vm:hover{background-color:blue} @@ -687,22 +659,18 @@ describe('@stylexjs/babel-plugin', () => { ).toMatchInlineSnapshot(` "@property --x-color { syntax: "*"; inherits: false;} @keyframes x35atj5-B{0%{box-shadow:1px 2px 3px 4px red;color:yellow;}100%{box-shadow:10px 20px 30px 40px green;color:var(--orange-theme-color);}} - :root, .xbiwvf9{--x19twipt:2px;--xypjos2:4px;--x1ec7iuc:8px;} - :root, .xsg933n{--xpqh4lw:blue;--x8nt2k2:10px;--xkxfyv:red;} - @media (prefers-color-scheme: dark){:root, .xsg933n{--xkxfyv:lightblue;}} - @media (min-width: 600px){:root, .xsg933n{--x8nt2k2:20px;}} @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--xkxfyv:oklab(0.7 -0.3 -0.4);}}} .x1coplze.x1coplze, .x1coplze.x1coplze:root{--xpqh4lw:lightblue;} .x4hn0rr.x4hn0rr, .x4hn0rr.x4hn0rr:root{--x1ec7iuc:20px;--xypjos2:10px;--x19twipt:5px;} .xufgesz{--orange-theme-color:red} - .x1s2izit{padding:var(--x1ec7iuc)} + .x1s2izit{padding:8px} .xymmreb{margin:10px 20px} .x1bg2uv5{border-color:green} - @media (max-width: 1000px){.xio2edn.xio2edn{border-color:var(--xpqh4lw)}} + @media (max-width: 1000px){.xio2edn.xio2edn{border-color:blue}} @media (max-width: 500px){@media (max-width: 1000px){.xqiy1ys.xqiy1ys.xqiy1ys{border-color:yellow}}} .x13ah0pd{animation-name:x35atj5-B} .x14rh7hd{color:var(--x-color)} - .x18abd1y{outline-color:var(--xkxfyv)} + .x18abd1y{outline-color:lightblue} /* @ltr begin */.x1kmio9f{float:left}/* @ltr end */ /* @rtl begin */.x1kmio9f{float:right}/* @rtl end */ .x1skrh0i{text-shadow:1px 2px 3px 4px red} @@ -715,5 +683,139 @@ describe('@stylexjs/babel-plugin', () => { @media (max-width: 1000px){.x975j7z.x975j7z.x975j7z:where(.x-default-marker:active ~ *, :has(~ .x-default-marker:active)){background-color:orange}}" `); }); + + test('optimizeDefineVars: removes unused variables and inlines single-use', () => { + // Create a scenario with unused and single-use variables + const testSource = ` + import * as stylex from '@stylexjs/stylex'; + export const styles = stylex.create({ + root: { + margin: vars.marginTokens, + // Note: blue and colorTokens are not used + }, + }); + `; + + const { metadata } = transform(testSource); + + // With optimization enabled (default) - should remove unused variables + expect( + stylexPlugin.processStylexRules(metadata, { + useLayers: false, + enableLTRRTLComments: false, + optimizeDefineVars: true, + }), + ).toMatchInlineSnapshot(` + "@supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .margin-xq7al5z:not(#\\#){margin:20px}" + `); + + // With optimization disabled - should keep all variables + expect( + stylexPlugin.processStylexRules(metadata, { + useLayers: false, + enableLTRRTLComments: false, + optimizeDefineVars: false, + }), + ).toMatchInlineSnapshot(` + ":root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} + :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} + @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} + @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} + @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .margin-xq7al5z:not(#\\#){margin:var(--marginTokens-x8nt2k2)}" + `); + }); + + test('optimizeDefineVars: inlines variables used only once', () => { + const testSource = ` + import * as stylex from '@stylexjs/stylex'; + export const styles = stylex.create({ + root: { + color: vars.blue, + // blue is only used once, should be inlined + }, + }); + `; + + const { metadata } = transform(testSource); + + // With optimization - blue should be inlined, not defined as a variable + expect( + stylexPlugin.processStylexRules(metadata, { + useLayers: false, + enableLTRRTLComments: false, + optimizeDefineVars: true, + }), + ).toMatchInlineSnapshot(` + "@supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .color-x1arqqxh:not(#\\#){color:blue}" + `); + + // Without optimization - blue should be defined as a variable + expect( + stylexPlugin.processStylexRules(metadata, { + useLayers: false, + enableLTRRTLComments: false, + optimizeDefineVars: false, + }), + ).toMatchInlineSnapshot(` + ":root, .xsg933n{--blue-xpqh4lw:blue;--marginTokens-x8nt2k2:10px;--colorTokens-xkxfyv:red;} + :root, .xbiwvf9{--small-x19twipt:2px;--medium-xypjos2:4px;--large-x1ec7iuc:8px;} + @media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:lightblue;}} + @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px;}} + @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .color-x1arqqxh:not(#\\#){color:var(--blue-xpqh4lw)}" + `); + }); + + test('optimizeDefineVars: preserves multi-use variables', () => { + const testSource = ` + import * as stylex from '@stylexjs/stylex'; + export const styles = stylex.create({ + root: { + margin: vars.marginTokens, + padding: vars.marginTokens, + // marginTokens is used twice, should not be inlined + }, + }); + `; + + const { metadata } = transform(testSource); + + // With optimization - marginTokens should remain as a variable since used multiple times + expect( + stylexPlugin.processStylexRules(metadata, { + useLayers: false, + enableLTRRTLComments: false, + optimizeDefineVars: true, + }), + ).toMatchInlineSnapshot(` + ":root, .xsg933n{--marginTokens-x8nt2k2:10px} + @media (min-width: 600px){:root, .xsg933n{--marginTokens-x8nt2k2:20px}} + @supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .margin-xq7al5z:not(#\\#){margin:var(--marginTokens-x8nt2k2)} + .padding-xe5wzq4:not(#\\#){padding:var(--marginTokens-x8nt2k2)}" + `); + }); + + test('optimizeDefineVars defaults to true', () => { + const testSource = ` + import * as stylex from '@stylexjs/stylex'; + export const styles = stylex.create({ + root: { + margin: vars.marginTokens, + }, + }); + `; + + const { metadata } = transform(testSource); + + // When no config is provided, optimization should be enabled by default + expect(stylexPlugin.processStylexRules(metadata)).toMatchInlineSnapshot(` + "@supports (color: oklab(0 0 0)){@media (prefers-color-scheme: dark){:root, .xsg933n{--colorTokens-xkxfyv:oklab(0.7 -0.3 -0.4);}}} + .margin-xq7al5z:not(#\\#){margin:20px}" + `); + }); }); }); diff --git a/packages/@stylexjs/babel-plugin/src/index.d.ts b/packages/@stylexjs/babel-plugin/src/index.d.ts index 92eb029ad..52b58e0c5 100644 --- a/packages/@stylexjs/babel-plugin/src/index.d.ts +++ b/packages/@stylexjs/babel-plugin/src/index.d.ts @@ -42,6 +42,7 @@ declare function processStylexRules( useLayers?: boolean; enableLTRRTLComments?: boolean; legacyDisableLayers?: boolean; + optimizeDefineVars?: boolean; }, ): string; export type StyleXTransformObj = Readonly<{ diff --git a/packages/@stylexjs/babel-plugin/src/index.js b/packages/@stylexjs/babel-plugin/src/index.js index 7b4648a01..6974a03c7 100644 --- a/packages/@stylexjs/babel-plugin/src/index.js +++ b/packages/@stylexjs/babel-plugin/src/index.js @@ -389,6 +389,137 @@ function getLogicalFloatVars(rules: Array): string { : ''; } +function optimizeDefineVarsRules(rules: Array): { + optimizedRules: Array, + varsToInline: Map, +} { + const defineVarsVariables: Map = new Map(); + const varUsageCount: Map = new Map(); + + for (const [, ruleObj] of rules) { + const { ltr, rtl } = ruleObj; + const isDefineVarsRule = /^(?:@[^{]*\{)?:root,\s*\.[\w-]+\{/.test(ltr); + + if (isDefineVarsRule) { + const varMatches = ltr.matchAll(/--([A-Za-z0-9_-]+):([^;}]+);?/g); + for (const match of varMatches) { + const varName = `--${match[1]}`; + const varValue = match[2].trim(); + defineVarsVariables.set(varName, varValue); + varUsageCount.set(varName, 0); + } + + if (rtl) { + const rtlVarMatches = rtl.matchAll(/--([A-Za-z0-9_-]+):([^;}]+);?/g); + for (const match of rtlVarMatches) { + const varName = `--${match[1]}`; + const varValue = match[2].trim(); + if (!defineVarsVariables.has(varName)) { + defineVarsVariables.set(varName, varValue); + varUsageCount.set(varName, 0); + } + } + } + } + } + + for (const [, ruleObj] of rules) { + const { ltr, rtl } = ruleObj; + const isDefineVarsRule = /^(?:@[^{]*\{)?:root,\s*\.[\w-]+\{/.test(ltr); + + if (!isDefineVarsRule) { + const ltrVarRefs = ltr.matchAll(/var\((--[A-Za-z0-9_-]+)(?:,|,\s|\))/g); + for (const match of ltrVarRefs) { + const varName = match[1]; + if (defineVarsVariables.has(varName)) { + varUsageCount.set(varName, (varUsageCount.get(varName) || 0) + 1); + } + } + + if (rtl) { + const rtlVarRefs = rtl.matchAll(/var\((--[A-Za-z0-9_-]+)(?:,|,\s|\))/g); + for (const match of rtlVarRefs) { + const varName = match[1]; + if (defineVarsVariables.has(varName)) { + varUsageCount.set(varName, (varUsageCount.get(varName) || 0) + 1); + } + } + } + } + } + + const varsToInline: Map = new Map(); + for (const [varName, count] of varUsageCount.entries()) { + if (count === 1) { + const value = defineVarsVariables.get(varName); + if (value && !value.includes('var(')) { + varsToInline.set(varName, value); + } + } + } + + const varsToRemove: Set = new Set(); + for (const [varName, count] of varUsageCount.entries()) { + if (count === 0) { + varsToRemove.add(varName); + } + } + + const optimizedRules: Array = rules + .map(([key, ruleObj, priority]) => { + const { ltr: initialLtr, rtl: initialRtl, ...rest } = ruleObj; + let ltr = initialLtr; + let rtl = initialRtl; + const isDefineVarsRule = /^(?:@[^{]*\{)?:root,\s*\.[\w-]+\{/.test(ltr); + + if (isDefineVarsRule) { + const allVarsToRemove = new Set([ + ...varsToRemove, + ...varsToInline.keys(), + ]); + + for (const varName of allVarsToRemove) { + const regex = new RegExp( + `${varName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}:[^;}]+;?`, + 'g', + ); + ltr = ltr.replace(regex, ''); + if (rtl) { + rtl = rtl.replace(regex, ''); + } + } + + ltr = ltr + .replace(/;\s*;/g, ';') + .replace(/\{\s*;/g, '{') + .replace(/;\s*\}/g, '}'); + if (rtl) { + rtl = rtl + .replace(/;\s*;/g, ';') + .replace(/\{\s*;/g, '{') + .replace(/;\s*\}/g, '}'); + } + + if (/\{\s*\}/.test(ltr)) { + return null; + } + } else { + for (const [varName, value] of varsToInline.entries()) { + const varRef = `var(${varName})`; + ltr = ltr.replaceAll(varRef, value); + if (rtl) { + rtl = rtl.replaceAll(varRef, value); + } + } + } + + return [key, { ltr, rtl, ...rest }, priority]; + }) + .filter(Boolean); + + return { optimizedRules, varsToInline }; +} + function processStylexRules( rules: Array, config?: @@ -398,6 +529,7 @@ function processStylexRules( enableLTRRTLComments?: boolean, legacyDisableLayers?: boolean, useLegacyClassnamesSort?: boolean, + optimizeDefineVars?: boolean, ... }, ): string { @@ -406,15 +538,23 @@ function processStylexRules( enableLTRRTLComments = false, legacyDisableLayers = false, useLegacyClassnamesSort = false, + optimizeDefineVars = true, } = typeof config === 'boolean' ? { useLayers: config } : (config ?? {}); if (rules.length === 0) { return ''; } - const constantRules = rules.filter( + // Optimize defineVars if requested + let processedRules = rules; + if (optimizeDefineVars) { + const optimizeResult = optimizeDefineVarsRules(rules); + processedRules = optimizeResult.optimizedRules; + } + + const constantRules = processedRules.filter( ([, ruleObj]) => ruleObj?.constKey != null && ruleObj?.constVal != null, ); - const nonConstantRules = rules.filter( + const nonConstantRules = processedRules.filter( ([, ruleObj]) => !(ruleObj?.constKey != null && ruleObj?.constVal != null), );