You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 17中App组件className丢失问题求助

问题描述

我用React 17编写了一个App组件用于页面渲染,App组件引入App.module.scss中的styles.uiStage作为div的className。项目启动后,该div的className丢失,但style标签中存在ui-stage样式,且所有子组件的className均可正常渲染。相关代码及rollup配置文件如下,请问问题原因是什么?

App.tsx

import React from 'react';

import styles from './App.module.scss';

type AppProps = {
  templateString: string;
}

const App: React.FC<AppProps> = ({
  templateString = ''
}) => {
  return <div className={styles.uiStage}>
    123
  </div>;
};

export default App;

App.module.scss

.ui-stage {
  background-color: red;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

index.ts

const root = document.getElementById('root');
ReactDOM.render(<App />, root);

rollup.config.js

import serve from "rollup-plugin-serve";
import livereload from "rollup-plugin-livereload";
import babel from '@rollup/plugin-babel';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import replace from '@rollup/plugin-replace';
import image from '@rollup/plugin-image';
import postcss from 'rollup-plugin-postcss';

const extensions = [".js", ".jsx", ".ts", ".tsx"];

export default {
  input: "src/index.ts",
  output: [
    {
      file: "dist/iife/bundle.js",
      format: "iife", // for local dev
      sourcemap: true,
    },
    {
      file: "dist/esm/bundle.js",
      format: 'esm', // for esm
      sourcemap: true,
    }
  ],
  plugins: [
    image(),
    postcss({
      autoModules: true,
      extensions: [".css", ".scss"],
    }),
    nodeResolve({
      extensions,
    }),
    replace({
      preventAssignment: true,
      'process.env.NODE_ENV': JSON.stringify( 'development' )
    }),
    commonjs(),
    babel({
      babelHelpers: 'bundled',
      extensions
    }),
    serve({
      open: true,
      verbose: true,
      contentBase: ["", "public"],
      host: "localhost",
      port: 3000,
    }),
    livereload({ watch: "dist" }),
  ]
};

问题原因及解决办法

核心原因

问题出在rollup-plugin-postcss的模块转换逻辑上:

  • 你SCSS里的类名是ui-stage(短横线命名),组件里用的是styles.uiStage(小驼峰),虽然插件autoModules: true默认会把短横线转驼峰,但主App组件的样式模块没有被正确映射,导致styles.uiStage的值为undefined,所以div上没渲染出className。
  • 子组件正常是因为它们的样式模块处理顺序或逻辑没触发这个冲突。

解决办法

  1. 明确配置postcss模块规则:替换autoModules为modules选项,强制开启驼峰转换:
postcss({
  modules: {
    camelCase: true, // 强制将短横线类名转为驼峰
    generateScopedName: '[name]__[local]--[hash:base64:5]' // 可选,自定义作用域类名格式
  },
  extensions: [".css", ".scss"],
})
  1. 直接使用短横线属性名:把组件里的styles.uiStage改成styles['ui-stage'],跳过驼峰转换步骤:
return <div className={styles['ui-stage']}>
  123
</div>;
  1. 调整插件执行顺序:确保postcss插件在babel、commonjs之前执行,避免样式模块解析延迟导致的映射丢失。

内容的提问来源于stack exchange,提问作者ChenLee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:22:41