StyleX 是编译时 CSS-in-JS 工具,禁止在组件中动态调用 stylex 函数;仅支持字面量或导入常量对象创建样式,动态组合须用 stylex.props(限布尔/枚举),跨组件合并须用 stylex.compose,且需正确配置 Babel 插件与 TypeScript 环境。

StyleX 不是运行时 CSS-in-JS,别在组件里调用 stylex 函数传动态对象
很多人看到 stylex 是个函数,第一反应是像 clsx 或 styled 那样在组件里拼样式对象。这是最典型的误用:StyleX 的核心机制是编译时静态分析,所有样式必须能被 Babel 插件在构建阶段“看懂”。传入变量、计算属性、Object.assign 或解构对象都会导致编译失败或退化为运行时内联 style。
正确写法只允许字面量对象或导入的常量对象:
import stylex from 'stylex';
// ✅ 正确:纯字面量
const styles = stylex.create({
button: {
backgroundColor: 'blue',
padding: '8px 16px',
borderRadius: '4px',
},
});
// ✅ 正确:从模块导入的常量
import { common } from './sharedStyles';
const styles = stylex.create({
root: { ...common.flexCenter, color: 'black' },
});
// ❌ 错误:含变量或表达式
const size = props.size;
const styles = stylex.create({ btn: { padding: size === 'sm' ? '4px 8px' : '8px 16px' } });
stylex.props 是唯一安全的动态组合入口,但仅限布尔/枚举值
stylex.props 是 StyleX 提供的、被 Babel 明确支持的动态样式组合方式。它不接受任意 JS 表达式,只接受已知键名(必须提前声明在 stylex.create 中)和有限的值类型:布尔值、字符串字面量、数字字面量,以及 null/undefined(用于条件剔除)。
- 它背后生成的是原子类名组合,不是运行时拼字符串
- 所有可能的变体(如
variant="primary"、disabled={true})必须在stylex.create中显式定义,否则编译报错 - 不能用于响应式断点切换(如
md:padding),那些需靠@media规则在 CSS 中处理
示例:
const styles = stylex.create({
button: {
backgroundColor: 'gray',
cursor: 'pointer',
},
primary: {
backgroundColor: 'blue',
},
disabled: {
opacity: 0.5,
cursor: 'not-allowed',
},
});
function Button({ variant, disabled }) {
// ✅ 合法:variant 和 disabled 都是预定义键,值是字面量
const [className, style] = stylex.props(
styles.button,
variant === 'primary' && styles.primary,
disabled && styles.disabled,
);
return <button classname="{className}" style="{style}">Click</button>;
}
跨组件合并样式必须用 stylex.compose,别用字符串拼接
大型应用中,Button 组件要支持用户传入自定义样式(比如图标区域额外 margin),你不能让使用者写 className={`${baseClass} ${userClass}``>——这会破坏原子性,也绕过 StyleX 的冲突检测。
必须用 stylex.compose,它会在编译时把多个原子类合并为一个新原子类,并确保特异性一致:
import stylex from 'stylex';
const buttonStyles = stylex.create({ root: { padding: '8px 16px' } });
const iconStyles = stylex.create({ spacer: { marginRight: '4px' } });
// ✅ 正确:compose 生成新原子类,无特异性叠加风险
const composed = stylex.compose(buttonStyles.root, iconStyles.spacer);
// ❌ 错误:字符串拼接导致两个独立类,可能被其他规则意外覆盖
const bad = `${buttonStyles.root} ${iconStyles.spacer}`;
注意:stylex.compose 参数只能是 stylex.create 返回的样式键,不能是字符串、变量或运行时计算结果。
TypeScript 类型推导依赖 @stylexjs/babel-plugin 的完整配置
StyleX 的类型安全不是靠 .d.ts 文件自动补全,而是靠 Babel 插件在编译时注入类型信息。如果没配好插件,VS Code 里 stylex.props 的参数不会提示可用变体,stylex.create 里的属性也不会校验是否是合法 CSS 属性。
关键检查点:
- Babel 配置中
@stylexjs/babel-plugin必须在@babel/preset-react之后、@babel/preset-typescript之前 - 插件选项
dev: true在开发环境开启类型注入,生产环境设为false关闭 - TSConfig 中
types字段需包含stylex,且项目根目录下要有stylex.d.ts(由插件生成)
漏掉任一环,就会出现 “Property ‘hoverBackgroundColor’ does not exist on type” 这类看似类型错误、实为插件未生效的问题。
真正难的不是写对某一行代码,而是让整个工具链在数万组件规模下保持编译可预测——StyleX 的原子类名、哈希稳定性和文件级缓存,都是为这个目标服务的。一旦配置漂移或插件顺序错乱,类型和构建行为就不可控了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











