StyleX defineVars Not Applying in Next.js(turboRepo) Project

92 Views Asked by At

I am working on a Next.js(turboRepo) project with StyleX for styling, and I am encountering an issue where the design tokens defined with stylex.defineVars are not being applied as expected. Here's the overview of my project structure and relevant configurations:

├── README.md
├── apps
|  ├── docs
|  |  ├── README.md
|  |  ├── app
|  |  |  ├── favicon.ico
|  |  |  ├── globals.css
|  |  |  ├── layout.tsx
|  |  |  ├── page.module.css
|  |  |  └── page.tsx
|  |  ├── next-env.d.ts
|  |  ├── next.config.js
|  |  ├── package.json
|  |  ├── public
|  |  |  ├── circles.svg
|  |  |  ├── next.svg
|  |  |  ├── turborepo.svg
|  |  |  └── vercel.svg
|  |  └── tsconfig.json
|  └── web
|     ├── README.md
|     ├── app
|     |  ├── Counter.tsx
|     |  ├── Provider.tsx
|     |  ├── apis
|     |  |  └── log.ts
|     |  ├── favicon.ico
|     |  ├── find-password
|     |  |  └── page.tsx
|     |  ├── globals.css
|     |  ├── hooks
|     |  |  ├── redux
|     |  |  |  └── index.ts
|     |  |  └── swr
|     |  |     └── useLogs.ts
|     |  ├── layout.tsx
|     |  ├── log
|     |  |  └── page.tsx
|     |  ├── login
|     |  |  └── page.tsx
|     |  ├── mypage
|     |  |  └── page.tsx
|     |  ├── page.module.css
|     |  ├── page.tsx
|     |  ├── signup
|     |  |  └── page.tsx
|     |  ├── store
|     |  |  ├── counterSlice.ts
|     |  |  └── store.ts
|     |  ├── types
|     |  |  └── log.ts
|     |  └── utils
|     |     └── fetcher.ts
|     ├── next-env.d.ts
|     ├── next.config.js
|     ├── package.json
|     └── tsconfig.json
├── package-lock.json
├── package.json
├── packages
|  ├── eslint-config
|  |  ├── README.md
|  |  ├── library.js
|  |  ├── next.js
|  |  ├── package.json
|  |  └── react-internal.js
|  ├── typescript-config
|  |  ├── base.json
|  |  ├── nextjs.json
|  |  ├── package.json
|  |  └── react-library.json
|  └── ui
|     ├── babel.config.js
|     ├── next.config.js
|     ├── package.json
|     ├── src
|     |  ├── button.tsx
|     |  ├── card.tsx
|     |  ├── code.tsx
|     |  ├── common.ts
|     |  ├── designToken.stylex.ts
|     |  └── quillEditor.tsx
|     ├── tsconfig.json
|     ├── tsconfig.lint.json
|     ├── turbo
|     |  └── generators
|     |     ├── config.ts
|     |     └── templates
|     |        └── component.hbs
|     └── turbo.json
├── tsconfig.json
└── turbo.json`

//packages/ui/.babelrc.js
const path = require("path");

module.exports = {
  presets: ["next/babel"],
  plugins: [
    [
      "@stylexjs/babel-plugin",
      {
        dev: process.env.NODE_ENV === "development",
        genConditionalClasses: true,
        treeshakeCompensation: true,
        unstable_moduleResolution: {
          type: "commonJS",
          rootDir: path.join(__dirname, "../.."),
        },
      },
    ],
  ],
};
//packages/ui/babel.config.js
import styleXPlugin from "@stylexjs/babel-plugin";

const config = {
  plugins: [
    [
      styleXPlugin,
      {
        dev: true,
        // Set this to true for snapshot testing
        // default: false
        test: false,
        // Required for CSS variable support
        unstable_moduleResolution: {
          // type: 'commonJS' | 'haste'
          // default: 'commonJS'
          type: "commonJS",
          // The absolute path to the root directory of your project
          rootDir: __dirname,
        },
      },
    ],
  ],
};

export default config;
//packages/ui/next.config.js
const stylexPlugin = require("@stylexjs/nextjs-plugin");

module.exports = stylexPlugin({
  rootDir: __dirname,
})({});
`
`
//packages/ui/package.json
{
  "name": "@repo/ui",
  "version": "0.0.0",
  "private": true,
  "exports": {
    "./button": "./src/button.tsx",
    "./card": "./src/card.tsx",
    "./code": "./src/code.tsx",
    "./common": "./src/common.ts",
    "./quillEditor": "./src/quillEditor.tsx",
    "./hotLogcard": "./src/main/hotLogCard.tsx",
    "./hotLogList": "./src/main/hotLogList.tsx",
    "./designToken.stylex": "./src/designToken.stylex.ts"
  },
  "scripts": {
    "lint": "eslint . --max-warnings 0",
    "generate:component": "turbo gen react-component"
  },
  "devDependencies": {
    "@repo/eslint-config": "*",
    "@repo/typescript-config": "*",
    "@stylexjs/babel-plugin": "^0.4.1",
    "@stylexjs/eslint-plugin": "^0.4.1",
    "@stylexjs/nextjs-plugin": "^0.4.1",
    "@turbo/gen": "^1.11.3",
    "@types/eslint": "^8.56.1",
    "@types/node": "^20.10.6",
    "@types/quill": "^2.0.14",
    "@types/react": "^18.2.46",
    "@types/react-dom": "^18.2.18",
    "eslint": "^8.56.0",
    "react": "^18.2.0",
    "typescript": "^5.3.3"
  },
  "dependencies": {
    "quill": "^1.3.7",
    "react-quill": "^2.0.0",
    "@stylexjs/stylex": "^0.4.1"
  }
}

The design tokens are defined in packages/ui/src/designToken.stylex.ts and are being imported and used in the apps/web/app components like this. import { colors, margins, titleStyle } from "@repo/ui/designToken.stylex";

Despite the correct import statements and seemingly proper configuration(I think), the styles are not reflected in the components.

I have already checked the module resolution, build processes, and ensured there are no errors in the console. The issue seems to be specific to the design tokens defined with stylex.defineVars.

Has anyone experienced a similar issue or can provide insights into what might be going wrong? Any suggestions or guidance would be greatly appreciated.

Thank you in advance!

I've also tried to apply the design tokens defined in packages/ui/src/designToken.stylex.ts using both relative and module resolution import methods in my Next.js components. Specifically, I used the following import statements

import { colors } from "../../../../packages/ui/src/designToken.stylex";
//apps/web/app/log/page.tsx
import { colors, margins, titleStyle } from "@repo/ui/designToken.stylex";
import QuillEditor from "@repo/ui/quillEditor";
import * as stylex from "@stylexjs/stylex";
// import { colors } from "../../../../packages/ui/src/designToken.stylex"

const styles = stylex.create({
...
autoSaveText: {
    color: colors.primary100,
    marginBottom: margins.extraLarge,
  },
...
});
const Log = () => {
  return (
...
<p {...stylex.props(styles.autoSaveText)}>자동 저장 21:10:27</p>
...
  );
};

export default Log;

In addition to the previous attempts, it's important to note that I did not initially set up StyleX in this project myself; it was configured by another team member. As a result, I am unsure why there are two separate Babel configuration files

1

There are 1 best solutions below

0
Derek Williams On

I am having similar issues, styling sometime not applied, and occasionally fonts not loading. My .babelrc.js is similar to yours. A workaround that I am using is to perform a fresh build by deleting the .next folder (e.g. rm -rf .next, then npm run build).

Content of my .babelrc.js

module.exports = {
  presets: ['next/babel'],
  plugins: [
    ['@babel/plugin-transform-private-methods'],
    [
      '@stylexjs/babel-plugin',
      {
        dev: process.env.NODE_ENV === 'development',
        runtimeInjection: false,
        genConditionalClasses: true,
        treeshakeCompensation: true,
        unstable_moduleResolution: {
          type: 'commonJS',
          rootDir: __dirname,
        },
      },
    ],
  ],
  env: {
    development: {
      compact: false,
    },
  },
}

Note that my rootDir does not include your '../..', and I am also loading a font.

So the workaround is the best that I can do now.

My next steps are to perform a diff on the 'working' vs 'non working' contents of the .next folder for those respective cases.

--UPDATE:

Comparing "non working" case to working case I found a difference that seems to cause the issue. The css file of the "working" version, located in .next/static/a2a455ca88da9b14.css was different than the "non working" version (that also had a different auto generated name, f23adbf2efd594d1.css). The "non-working" version is significantly shorter.

So my workaround of generating a new version of the .next folder by first deleting the existing .next folder works, it seems that the caching is somehow breaking the static css file between builds.

Note: found that the Stylex team is aware of the issue: https://github.com/facebook/stylex/issues/297 They also recommend using running prebuild script, see package.json from their example project here: https://github.com/facebook/stylex/blob/main/apps/nextjs-example/package.json