大家好,我是果汁,最近准备开一个新坑《三分钟通关系列》,旨在给还在观望新技术的童鞋一个快速了解的窗口,如果有兴趣可以关注一下这个系列,Thanks♪(・ω・)ノ。今天我们来通关的是 meta
公司新出的开源产品:StyleX
StyleX 是什么?
按官网原文来说如下
StyleX is a simple, easy to use JavaScript syntax and compiler for styling web apps.
简单来说,是一个快速构建应用样式的 JavaScript
语法编译器,这里注意它的定位并不是单纯的 css
预编译器,具体原因下面会解释。
和现有 cssinjs 库的异同
相同点
- 语法上都是用 js 来书写 css 属性,类似下面这样:
tsx
// stylex
import * as stylex from '@stylexjs/stylex';
const styles = stylex.create({
root: {
width: '100%',
maxWidth: 800,
minHeight: 40,
},
});
// aphrodite
import { StyleSheet } from "aphrodite";
const styles = StyleSheet.create({
navBarItem: {
flexDirection: "row",
fontSize: 16,
fontWeight: "300"
}
});
// styled-components
import styled from 'styled-components';
// Create a <Title> react component that renders an <h1> which is
// centered, palevioletred and sized at 1.5em
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
function MyUI() {
return (
<Title>Hello World, this is my first styled component!</Title>
);
}
// emotion
import { css } from '@emotion/css'
const color = 'white'
render(
<div
className={css`
padding: 32px;
background-color: hotpink;
font-size: 24px;
border-radius: 4px;
&:hover {
color: ${color};
}
`}
>)
可以看到,基本上语法分为两种,一种是直接按对象书写,另一种是直接写 css
字符串,两种方式各有优点, css
字符串更贴近原生,但是类型没法接入,直接按对象书写虽然要改变书写 css
的习惯,但是可以保留类型。
- 都会生成
hash
来保证css
样式的作用域隔离,类似这样css-1h3ivcl
。 - 都可以很方便的和
js
进行交互,动态样式和定制主题都会非常方便。
不同点
cssinjs
库的弊端之一,昂贵的运行时消耗(runtime const),基本存在于所有cssinjs
库,StyleX
不同于常规cssinjs
库,它几乎可以做到 0 运行时(zero runtime),得益于他的架构,可以把同一文件的样式给抽离成css
文件,动态样式又可以以极低的成本运行,速度非常快。- 可以很方便的跨文件复用组合样式,现在其他
cssinjs
库很难做到。 - 可以准确的预测
css
最终渲染的优先级,最后写的样式的渲染时永远在最前面,而不会随js
执行顺序发生偏差。 - 提供类型支持,可以很方便的约束每个样式对象里的属性。
- 并不提供完整的 css 选择器功能,为了使应用可预测,一些伪类选择器可能并不支持,比如
.className > *
、.className ~ *
、.className:hover > div:first-child
等,这也是为什么不说他是css
预编译器的原因,从底层就限制了某些语法。
StyleX 的目标
作为 cssinjs 的终极解决方案
虽然用例都是 React
的例子,但 StyleX
并不是 CSS-in-React
的解决方案,目标是作为通用 cssinjs
的解决方案,本身是支持使用 jsx
或者 模板字符串等的框架。最终是希望在提高开发体验的同时,runtime
的性能也要好。
方便的共享样式
StyleX
旨在创建一个系统,可以轻松可靠地共享样式以及 NPM
上包内的组件。
更快的样式加载速度
StyleX
经过优化,可生成预先加载的单个高度优化的 CSS
包, 目的是以足够快的方式预先加载所有的 css
。
更简单的上手方式
StyleX
常用的 API
就两个,stylex.create
和 stylex.props
,一个用来创建样式,一个用来应用样式,非常简单,心智成本基本没有。
上手体验
了解了 StyleX
的大体能力后,我们现在来实战上手体验一下,首先我们先初始化 vite
脚手架:
pnpm
pnpm create vite stylex-demo --template react-ts
初始完之后,安装依赖
pnpm
pnpm install --save @stylexjs/stylex
安装编译插件,由于脚手架是 vite
,所以我们安装 vite-plugin-stylex
的插件, 具体安装什么根据自己项目的构建器来选择,官网指路。
顺便一提,
StyleX
是支持快速本地调试开发的,如果觉得短时间不会上线,可以直接用这个包@stylexjs/dev-runtime
来进行本地开发,就不需要装编译插件了,官网指路。
pnpm
$ pnpm install --save-dev vite-plugin-stylex
同时我们在 vite.config.ts
里面配置插件
ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import stylexPlugin from "vite-plugin-stylex";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), stylexPlugin()],
});
准备就绪,现在我们修改 App.tsx
里的样式代码,改成 StyleX
的写法:
diff
+ import * as stylex from "@stylexjs/stylex";
+ const styles = stylex.create({
+ stylexTest: {
+ color: "red",
+ fontWeight: "blod"
+ },
+ });
function App() {
return (
+ <div {...stylex.props(styles.stylexTest)}>
StyleX Test
</div>
);
}
export default App;
然后我们就能在浏览器上看到样式出来了

让我们打开控制台看看,可以发现开发环境下,并不会自动生成 css 文件,而是走正常的编译流程

然后我们再打包看看,会发现打包的时候多了一个 stylex.28b4cb32.css
的样式文件

启动本地服务器查看线上生产环境

可以发现 css
样式已经被固化到 css
文件里了,现在和正常的 html
、 css
页面没啥区别了,已经没有 cssinjs
的运行时开销,现在可以说是零运行时。那问题来了如果是动态样式会怎么样呢?,我们修改下之前的文件
tsx
import * as stylex from "@stylexjs/stylex";
import { useState } from "react";
const styles = stylex.create({
stylexTest: (color) => ({
color,
fontWeight: "blod",
}),
});
function App() {
const [color, setColor] = useState<"red" | "blue">("red");
return (
<div {...stylex.props(styles.stylexTest(color))}>
StyleX Test
<br />
<button onClick={() => setColor(color === "red" ? "blue" : "red")}>
Change Color
</button>
</div>
);
}
export default App;
运行后发现,之前的静态样式被替换成了 cssvar
,没错,这就是 StyleX
对动态样式的解决方案,这样切换样式只需要修改 cssvar
的值,由于原生切换基本没有啥性能损耗,所以我们可以理解为 StyleX
的动态样式的 runtime
性能也是非常好的。

demo 我放到 github 上了,有需要的童鞋自取,戳 stylex-demo
总结
可以看到,StyleX
作为 cssinjs
的解决方案,已经吸取了老牌库的经验教训,摸索出了一条自己的路,目前看来确实比其他库来的更加优秀,性能上也更好。项目目前还在起步阶段,有兴趣的童鞋可以移步官网进行了解,作为 meta
的开源作品,我相信质量是可以保证的,就看后面的生态发展如何了,让我们拭目以待吧!