查看原文
其他

StyleX:Meta 公司开源的 CSS-in-JS 解决方案

小懒 FED实验室 2024-02-12
关注下方公众号,获取更多热点资讯

相信坚持的力量!今天是坚持日更的第117天,点击关注、点赞、在看支持我

2021年,Facebook (2021年10月已更名为 Meta) 公司的软件工程师 Naman Goel 在 React Finland 大会上展示了 Stylex。Stylex 是 Facebook 为新的 facebook.com 网站定制的 CSS-in-JS 解决方案。StyleX 缓解了大型 React 应用程序 CSS-in-JS 的关键痛点,包括未使用的样式、大型 CSS 文件、CSS-in-JS 库大小。

StyleX 介绍

StyleX 是一个强大的、富有表现力的,具有确定性、可靠性和可扩展性的样式系统。它从其他的样式库中汲取了最佳的思想,创造出了一些既熟悉又独特的功能。

StyleX 借助编译时的工具将 CSS-in-JS 库的开发人员体验与静态 CSS 的性能和可扩展性相结合。然而,StyleX 不仅仅是另一个基于编译器的CSS-in-JS 库。它经过精心设计,以满足大型应用程序、可重用组件库和静态类型代码库的要求。以下是 StyleX 的几个特点:

  • StyleX 支持表达性的 CSS 子集。它避免了复杂的选择器,并保证在生成的 CSS 中不会产生特定冲突。
  • StyleX 将样式转换、组织和优化为“原子” CSS 类名。不需要学习或管理单独的实用程序类名库。
  • StyleX 允许样式在文件和组件边界合并,非常适合允许用户自定义的组件库。
  • StyleX 是完全类型化的,并提供类型实用工具,以允许对组件可以接受的属性和值进行精细控制。

StyleX 的主要特性

  • 快速:StyleX 在编译时和运行时都具备高效的性能。Babel转换不会显著减慢构建速度。在运行时,StyleX 完全避免了在运行时使用 JavaScript 插入样式所涉及的成本,并且只在必要时有效地合并类名字符串。生成的 CSS 经过优化,确保即使对于大型网站的样式也可以被快速解析。

  • 可擴展:StyleX 旨在適應像 Meta 這樣的超大型代碼庫。通過原子構建和文件級緩存,Babel 插件能夠處理數萬個組件在編譯時的樣式處理。由於 StyleX 設計為封裝樣式,它允許在隔離環境中開發新組件,並期望一旦在其他組件中使用時能夠可預測地呈現。通过生成原子 CSS 类名,StyleX有助于最小化 CSS 捆绑包的大小。随着应用程序中组件数量的增长,CSS 捆绑包的大小开始趋于平稳。这使得开发人员无需手动优化或延迟加载CSS文件。

  • 可预测:StyleX 會自動管理 CSS 選擇器的特異性,以確保生成的規則之間不會發生衝突。它為開發人員提供了一個可靠地應用樣式的系統,並確保 「最後應用的樣式始終生效」。

  • 可组合:StyleX 样式易于组合。不仅可以条件地应用多个本地样式,还可以在文件和组件之间传递样式。样式始终以可预测的结果进行合并。

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

  • Colocation:StyleX 允许和鼓励在使用它们的组件相同文件中编写样式。这种共享位置有助于使样式在长期内更易读和可维护。StyleX能够使用静态分析和构建时工具来消除组件之间的样式重复和未使用的样式。

  • 可测试:StyleX 可以配置为输出调试类名,而不是功能性的原子类名。这可以用于生成在响应较小的设计更改时不经常更改的快照。

StyleX 的工作原理

StyleX 是一组协同工作的工具集组成的,包括:

  • 一个 Babel 插件
  • 一个小型运行时库
  • 一个 ESlint 插件
  • 与捆绑器和框架的集成不断增加。

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

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

在使用更强大的模式(如样式组合)时,一个小型的运行时会动态地合并类名对象。这个运行时已经经过优化,速度非常快,并且结果被缓存。

StyleX 快速上手

import * as stylex from 'stylex';
const styles = stylex.create({
  red: {color'red'},
});
let a = stylex.props(styles.red);

编译后的 js:

import * as stylex from 'stylex';

let a = {className'x1e2nbdu'};

编译后的 CSS:

.x1e2nbdu { color: red; }

Meta 的目标是使 StyleX 尽可能简约和易学。因此,他们不想发明太多的 API。相反,他们希望能够尽可能地利用常见的 JavaScript 模式,并提供尽可能小的 API 表面。

StyleX 的核心可以归结为两个功能:

  • stylex.create
  • stylex.props

stylex.create 用于创建样式,stylex.props 用于将这些样式应用到元素中。

在这两个函数中,选择使用常见的 JS 模式,而不是为 StyleX 引入独特的 API 或模式。例如,StyleX 没有用于条件样式的 API。相反,它们支持使用布尔或三元表达式有条件地应用样式。

在处理 JavaScript 对象和数组时,一切都应按预期进行。

Meta 如何使用 StyleX?

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

Meta 扩展了 StyleX 的原始功能,使 Meta 的工程师可以使用 StyleX 来编写静态和动态样式。他们正在使用 StyleX 的主题 API 来开发可针对不同 Meta 产品中使用的不同设计系统外观的“通用”组件。通过与 React Native 的样式系统引入的封装原则相一致,Meta 正在逐步扩展对跨平台样式的支持。

大家都在看

继续滑动看下一个

StyleX:Meta 公司开源的 CSS-in-JS 解决方案

小懒 FED实验室
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存