跳至主要内容

介绍 StyleX

·阅读 7 分钟
Naman Goel
Nicolas Gallagher

我们很高兴地推出 StyleX。StyleX 是一款用于大型应用的表达性、确定性、可靠性和可扩展的样式系统。我们借鉴了之前样式库的最佳理念,创造出既熟悉又独具特色的全新产品。

什么是 StyleX?

StyleX 采用了 CSS-in-JS 库的开发者体验,并利用编译时工具将其与静态 CSS 的性能和可扩展性相结合。然而,StyleX 不仅仅是另一个基于编译器的 CSS-in-JS 库。StyleX 经过精心设计,以满足大型应用、可重用组件库和静态类型代码库的要求。

  1. StyleX 支持 CSS 的表达性子集。它避免使用复杂的选取器,并保证生成的 CSS 中不会出现特异性冲突。
  2. StyleX 将样式转换为“原子”CSS 类名,并对其进行组织和优化。无需学习或管理单独的实用程序类名库。
  3. StyleX 允许跨文件和组件边界合并样式,使其成为允许用户自定义的组件库的理想选择。
  4. StyleX 具有完整的类型化功能,并提供类型实用程序,以便对组件可以接受的属性和值进行细粒度控制。

StyleX 的优势是什么?

快速

StyleX 的设计目标是在编译时和运行时都快速。Babel 转换不会显著减慢构建速度。

在运行时,StyleX 完全避免了使用 JavaScript 在运行时插入样式相关的成本,并且仅在必要时有效地组合类名字符串。生成的 CSS 经过尺寸优化,确保即使是最大网站的样式也能被浏览器快速解析。

可扩展

StyleX 旨在扩展到极大的代码库,例如我们在 Meta 中使用的代码库。Babel 插件可以通过利用原子构建和文件级缓存,在编译时处理数千个组件中的样式。由于 StyleX 旨在封装样式,因此它允许在隔离环境中开发新组件,并期望它们在与其他组件一起使用时能够以可预测的方式呈现。

通过生成原子 CSS 类名,StyleX 有助于最大程度地减少 CSS 包的大小。随着应用中组件数量的增加,CSS 包的大小开始趋于平稳。这使开发人员无需手动优化或延迟加载 CSS 文件。

可预测

StyleX 自动管理 CSS 选择器的特异性,以保证生成的规则之间不会发生冲突。StyleX 为开发人员提供了一个可靠地应用样式的系统,并确保“最后应用的样式始终有效”。

可组合

StyleX 样式易于组合。不仅可以根据条件应用多个局部样式,还可以跨文件和组件传递样式。样式始终以可预测的结果合并。

类型安全

您可以使用 TypeScript 或 Flow 类型来限制组件接受的样式。每个样式属性和变量都具有完整的类型化功能。

位置关联

StyleX 允许并鼓励在与使用它们的组件相同的文件中编写样式。从长远来看,这种位置关联有助于使样式更易于阅读和维护。StyleX 能够使用静态分析和构建时工具来消除跨组件的样式重复,并删除未使用的样式。

可测试

StyleX 可以配置为输出调试类名,而不是功能性原子类名。这可以用于生成在响应轻微设计更改时不会频繁更改的快照。

StyleX 的工作原理是什么?

StyleX 是一组协同工作的工具。

  • Babel 插件
  • 小型运行时库
  • ESlint 插件
  • 越来越多的与捆绑器和框架的集成。

StyleX 最重要的部分是 Babel 插件。它查找并提取源代码中定义的所有样式,并在编译时将其转换为原子类名。辅助函数对收集的样式进行重复数据删除、排序和写入 CSS 文件。这些工具用于实现捆绑器插件。

为了使 StyleX 的使用尽可能自然,StyleX 支持各种静态模式,通过使用局部常量和表达式来定义样式。此外,为了提供最佳性能,Babel 插件还尽可能预先计算最终的类名,以消除任何运行时成本——甚至包括合并给定文件中的类名。如果组件在同一文件中静态定义和使用样式,则运行时成本将为 **零**。

当使用更强大的模式(例如样式组合)时,一个微小的运行时会动态合并类名对象。此运行时经过优化,速度极快,结果会被记忆化。

StyleX 的起源

之前的 Facebook 网站使用了类似于 CSS 模块的东西,并且遇到了各种问题,这些问题激发了 CSS-in-JS 的最初想法。访问 facebook.com 的普通访客将下载数十兆字节的 CSS。其中大部分未被使用。为了优化初始加载,我们将 CSS 延迟加载,这反过来会导致更新速度缓慢(或“交互到下一帧绘制”时间)。复杂选取器的使用会导致冲突或“特异性战争”。工程师经常求助于使用 !important 或更复杂的选取器来解决他们的问题,从而使整个系统变得越来越糟糕。

几年前,当我们使用 React 从头开始重建 facebook.com 时,我们知道我们需要更好的东西,于是构建了 StyleX。

StyleX 旨在实现可扩展性,并且其设计在我们多年的使用经验中得到了证明。我们向 StyleX 添加了新功能,而没有降低性能或可扩展性,同时使 StyleX 的使用更加愉快。

使用 StyleX 对我们 Meta 的可扩展性和表达性都产生了巨大的改进。在 facebook.com 上,我们能够将 CSS 包从数十兆字节的延迟加载 CSS 减少到几百千字节的单个包。

我们创建 StyleX 不仅是为了满足 Web 上 React 开发人员的样式需求,还旨在统一 Web 和原生环境下 React 的样式。

Meta 如何使用 StyleX?

StyleX 已成为 Meta 中每个 Web 表面样式化组件的首选方式。StyleX 用于为 Meta 的每个主要外部和内部产品样式化 React 组件,包括 Facebook、WhatsApp、Instagram、Workplace 和 Threads。它改变了我们编写组件的方式,并解决了我们的团队之前在无法封装和扩展其样式化组件方面遇到的问题。

我们扩展了 StyleX 的原始功能,以便 Meta 的工程师可以使用 StyleX 编写静态和动态样式。我们的团队正在使用 StyleX 主题 API 开发“通用”组件,这些组件经过主题化,以采用 Meta 不同产品中使用的不同设计系统的外观。并且由于 StyleX 与 React Native 的样式系统引入的封装原则保持一致,因此我们正在逐步扩展对跨平台样式的支持。

开源

我们开源的是我们在内部使用的内容。我们首先在 Github 上进行开发,然后将其同步回 Meta。尽管 StyleX 最初是在 Meta 为 Meta 创建的,但它并不特定于 Meta。

也就是说,这仅仅是个开始。我们期待与社区合作,引入进一步的优化和更多集成。

我们希望您像我们一样喜欢使用 StyleX。❤️