facebook / stylex

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

Uncaught Error: 'stylex.create' should never be called at runtime. It should be compiled away by '@stylexjs/babel-plugin' error occurs. #777

Open randolph-jang opened 5 days ago

randolph-jang commented 5 days ago

Describe the issue

※ I couldn’t find a solution from the following discussion: https://github.com/facebook/stylex/discussions/427

I am working in a Webpack + React + TypeScript + StyleX environment. In Webpack, both [babel-loader, ts-loader] are configured.

When running Webpack in development mode, the following error appears in the browser:

Uncaught Error: 'stylex.create' should never be called at runtime. It should be compiled away by '@stylexjs/babel-plugin'
    at eval (App.tsx:40:23)
    at ./src/App.tsx (main.js:503:1)
    at __webpack_require__ (main.js:993:32)
    at fn (main.js:1200:21)
    at eval (index.tsx:22:15)
    at ./src/index.tsx (main.js:514:1)
    at __webpack_require__ (main.js:993:32)
    at main.js:2071:37

This error occurs when using ts-loader as the file loader. ※ The issue does not occur when using babel-loader.

We need to use ts-loader for strong type-checking.

Please investigate and resolve this error so that StyleX can work with ts-loader.

Expected behavior

The web page should work correctly without errors.

Steps to reproduce

I have attached a project that can be tested as follows. stylex-ts-loader-test.zip

package.json

{
  "name": "ts-loader-test",
  "version": "0.1.0",
  "main": "index.js",
  "repository": "http://test",
  "license": "MIT",
  "scripts": {
    "bicheck": "biome check --write .",
    "build": "webpack --mode=production  --progress",
    "dev": "webpack-dev-server --mode=development --open --hot --progress",
    "format": "biome format --write .",
    "lint": "biome lint --write ."
  },
  "dependencies": {
    "@stylexjs/stylex": "^0.7.5",
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "react-i18next": "^15.0.2"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@babel/preset-react": "^7.24.7",
    "@babel/preset-typescript": "^7.24.7",
    "@biomejs/biome": "1.8.3",
    "@stylexjs/babel-plugin": "^0.7.5",
    "@stylexjs/dev-runtime": "^0.7.5",
    "@stylexjs/webpack-plugin": "^0.7.5",
    "@types/jest": "^29.5.12",
    "@types/js-beautify": "^1.14.3",
    "@types/react": "^18.3.3",
    "@types/react-dom": "^18.3.0",
    "babel-loader": "^9.1.3",
    "clean-webpack-plugin": "^4.0.0",
    "globals": "^15.9.0",
    "html-webpack-plugin": "^5.6.0",
    "prettier": "3.3.3",
    "ts-loader": "^9.5.1",
    "typescript": "^5.5.4",
    "webpack": "^5.93.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^5.0.4"
  }
}

webpack.config.js

const StylexPlugin = require('@stylexjs/webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('node:path');
const webpack = require('webpack');

module.exports = (env, argv) => {
  const prod = argv.mode === 'production';

  return {
    mode: prod ? 'production' : 'development',
    devtool: prod ? 'hidden-source-map' : 'eval',
    entry: './src/index.tsx',
    output: {
      path: path.join(__dirname, '/dist'),
      filename: '[name].js',
    },
    devServer: {
      port: 3000,
      hot: true,
    },
    resolve: {
      extensions: ['.ts', '.tsx', '.js', '.jsx'],
    },
    module: {
      rules: [
        {
          test: /\.(ts|tsx)$/,
          use: ['babel-loader', 'ts-loader'],
          exclude: /node_modules/,
        },
      ],
    },
    plugins: [
      new webpack.ProvidePlugin({
        React: 'react',
      }),
      new HtmlWebpackPlugin({
        template: './public/index.html',
        minify:
          process.env.NODE_ENV === 'production'
            ? {
                collapseWhitespace: true,
                removeComments: true,
              }
            : false,
      }),
      new CleanWebpackPlugin(),
      new StylexPlugin({
        filename: 'styles.[contenthash].css',
        dev: argv.mode === 'development',
        runtimeInjection: false,
        classNamePrefix: 'x',
        unstable_moduleResolution: {
          type: 'commonJS',
          rootDir: __dirname,
        },
      }),
    ],
  };
};

index.tsx

import inject from '@stylexjs/dev-runtime';
import { createRoot } from 'react-dom/client';
import { App } from './App';

if (process.env.NODE_ENV === 'development') {
  inject({
    classNamePrefix: 'x',
    dev: true,
    styleResolution: 'application-order',
    test: false,
    useRemForFontSize: false,
  });
}

const container = document.getElementById('root');
const root = createRoot(container!);
root.render(<App />);

App.tsx


import * as stylex from '@stylexjs/stylex';

const styles = stylex.create({
  base: {
    display: 'flex',
    margin: '0 auto',
    justifyContent: 'space-between',
  },
});

export const App = () => {
  return (
    <div {...stylex.props(styles.base)}>
      <h1>StyleX 테스트</h1>
    </div>
  );
};

The following is the execution result screen.

image

Please resolve the issue.

Test case

No response

Additional comments

No response

nmn commented 5 days ago

Would you be able to provide a small github repo with the setup that I can debug?