跳至主要内容

·阅读 4 分钟
Naman Goel

StyleX v0.8.0 现已发布,其中包含大量修复和新的 ESLint 规则。

代码风格检查增强

我们一直在对我们的 ESLint 插件进行大量改进。我们既改进了现有的规则,又添加了新的规则。感谢 Melissa Liu

以下是一些亮点

新的 valid-shorthands 规则

此规则强制执行我们关于何时以及如何使用 CSS 简写属性的意见。它不允许对简写使用多值简写,并且完全禁止某些属性。

const styles = stylex({
invalidShorthands: {
// border shorthands are entirely disallowed
// Use `borderWidth`, `borderStyle`, and `borderColor` instead
border: '1px solid black',
// Multiple values for different sides within the same shorthand are disallowed
borderWidth: '1px 2px 3px 4px',
margin: '10px 20px 30px',
padding: '10px 20px',
},
validShorthands: {
borderBottomWidth: 3,
borderColor: 'black',
borderInlineEndWidth: 2,
borderInlineStartWidth: 4,
borderStyle: 'solid',
borderTopWidth: 1,
marginBottom: 30,
marginInline: 20,
marginTop: 10,
paddingBlock: 10,
paddingInline: 20,
},
});

这些意见指导您使用最一致且最可重用的 CSS。

提示

此规则为所有不允许的属性提供了自动修复功能。

新的 enforce-extension 规则

此新规则强制执行 定义变量时的规则。它强制执行 stylex.defineVars 的用法是在具有 .stylex.js(或 '.ts' 或 '.jsx' 或 '.tsx')扩展名的文件中命名的导出,并且此类文件没有其他导出。

其他代码风格检查修复

我们已更新 ESLint 规则以包含其他缺少的属性和值。值得注意的是,valid-styles 规则现在应该理解

  • fieldSizing 作为有效属性
  • @starting-style 作为有效的 at 规则。

使用 lightningcss 进行后处理

StyleX 的编译过程在概念上是一个三步过程

  1. 转换 JavaScript 源文件以替换 stylex.create 等的用法,并使用生成的类名和收集生成的 CSS。
  2. 对所有收集到的 CSS 进行去重和排序。
  3. 将 CSS 写入文件。

但是,在将 CSS 写入文件之前,通常需要对其进行后处理。此后处理可以包括缩小、添加前缀或其他转换。经过多次讨论,我们决定将 lightningcss 标准化为此后处理。

作为第一步,我们默认情况下为我们的 Rollup 插件添加了 lightningcss。我们接下来将推出对其他捆绑器插件的支持。

感谢 Prakshal Jain 为此做出的贡献!

主题改进

我们对 StyleX 中的主题进行了两个小的但重要的改进。

使用 stylex.firstThatWorks 为 CSS 变量定义回退值

StyleX 有一个 stylex.firstThatWorks 函数,可用于为 CSS 属性定义回退值。这类似于在 CSS 中多次使用具有不同值的相同属性。

/* Represent this */
.my-class {
background-color: #808080;
background-color: oklab(0.5 0.5 0.5);
}
const styles = stylex.create({
myClass: {
// as:
backgroundColor: stylex.firstThatWorks(
'oklab(0.5 0.5 0.5)',
'#808080',
),
},
});

现在,相同的 API 也适用于 CSS 变量。

/* Represent this */
.my-class {
background-color: var(--bg-color, #808080);
}
const styles = stylex.create({
myClass: {
// as:
backgroundColor: stylex.firstThatWorks(
'var(--bg-color)',
'#808080',
),
},
});

主题比默认变量值具有更高的特异性

使用 stylex.createTheme 创建的 CSS 规则现在比使用 stylex.defineVars 创建的规则具有更高的特异性。

这在绝大多数情况下不应该成为问题,因为我们始终按正确的顺序对规则进行排序。但是,在您可能在同一页面上加载多个 StyleX CSS 文件的极端边缘情况下,此修复将确保一致性。

其他修复

我们对 StyleX 的各个部分进行了一些其他修复

  • **修复**:textAlign 的逻辑值不再转换为 leftright
  • 修复: [CLI]优雅地处理删除文件时的错误 (#695)
  • **特性**:扩展 CLI 的配置选项 (#638)
  • **修复**:不要为用于变量的数字值添加 'px' 单位 (#694)
    • **修复**:不要为接受原始数字作为值的附加属性添加 'px' 单位 (#705)

文档改进

我们添加了各种捆绑器插件选项的文档,并在我们的 生态系统页面 中添加了其他项目。

我们还更新了网站上的搜索,使其更全面和准确。(由 Algolia 提供支持)

·阅读 1 分钟
Naman Goel

StyleX v0.7.3 现已发布,其中修复了 Rollup 插件的问题,该插件以前没有在发布到 NPM 时包含所有必要的文件。

·阅读 2 分钟
Naman Goel

我们很高兴发布 StyleX v0.7.0,其中包含新的 CLI 以简化 StyleX 的入门过程、变量改进以及各种错误修复。

CLI

StyleX 依赖于一个编译器,该编译器转换您的 JavaScript 代码 *并* 生成一个静态 CSS 文件。但是,将此编译器与您的捆绑器集成可能很棘手。因此,虽然我们继续致力于提高捆绑器集成的质量,但我们引入了一个新的 CLI 作为替代方案!

CLI 转换整个文件夹。它生成一个输出文件夹,其中 StyleX 已被编译并生成了一个静态 CSS 文件。此外,CLI 将生成的 CSS 文件的导入语句插入到每个使用 StyleX 的文件中。

我们很高兴提供这种基于捆绑器的设置的替代方案,并选择以实验状态发布 CLI。我们希望了解您对它的使用体验以及您希望看到的改进。

特别感谢 Joel Austin 为 CLI 做出的贡献。

CSS 变量的文字名称

使用 stylex.defineVars 时,StyleX 会抽象掉实际的 CSS 变量名,并允许您将其用作 JavaScript 引用。在幕后,为每个变量生成唯一的变量名。

但是,在某些情况下,了解确切的变量名很有用。例如,当您可能希望在独立的 CSS 文件中使用该变量时。

为了解决此类用例,我们已更新 stylex.defineVars API 以原样使用以 -- 开头的文字。除了传递给 stylex.defineVars 的键之外,API 保持不变。

const vars = stylex.defineVars({
'--primary-color': 'red',
'--secondary-color': 'blue',
});
注意

使用变量名的文字时,StyleX 无法保证唯一性。

错误修复和改进

此外,还对类型、eslint 规则和捆绑器插件进行了错误修复。

·阅读 3 分钟
Naman Goel

我们很高兴发布 StyleX v0.6.1,其中包含一些用于处理 CSS 自定义属性(也称为“变量”)的大幅改进以及众多错误修复。

变量改进

我们添加了一些用于在 StyleX 中使用变量和主题的新功能和改进。

变量的回退值

您现在可以为使用 stylex.defineVars API 定义的变量提供回退值。此新功能没有引入任何新的 API。相反,现有的 stylex.firstThatWorks API 现在支持变量作为参数。

import * as stylex from '@stylexjs/stylex';
import {colors} from './tokens.stylex';

const styles = stylex.create({
container: {
color: stylex.firstThatWorks(colors.primary, 'black'),
},
});

支持使用回退变量列表。

类型化变量

StyleX 引入了一套全新的 API,用于为 CSS 变量定义 <syntax> 类型。这会导致在生成的 CSS 输出中出现 @property 规则,该规则可用于动画化 CSS 变量以及其他特殊用例。

定义变量时可以使用新的 stylex.types.* 函数来为其定义特定类型。

import * as stylex from '@stylexjs/stylex';

const typedTokens = stylex.defineVars({
bgColor: stylex.types.color<string>({
default: 'cyan',
[DARK]: 'navy',
}),
cornerRadius: stylex.types.length<string | number>({
default: '4px',
'@media (max-width: 600px)': 0,
}),
translucent: stylex.types.number<number>(0.5),
angle: stylex.types.angle<string>('0deg'),
shortAnimation: stylex.types.time<string>('0.5s'),
});

定义了类型的变量后,可以使用 stylex.keyframes 像任何其他 CSS 属性一样对其进行动画处理。

import * as stylex from '@stylexjs/stylex';
import {typedTokens} from './tokens.stylex';

const rotate = stylex.keyframes({
from: { [typedTokens.angle]: '0deg' },
to: { [typedTokens.angle]: '360deg' },
});

const styles = stylex.create({
gradient: {
backgroundImage: `conic-gradient(from ${tokens.angle}, ...colors)`,
animationName: rotate,
animationDuration: '10s',
animationTimingFunction: 'linear',
animationIterationCount: 'infinite',
},
})

这可以用于实现一些有趣的效果,例如动画化圆锥渐变的 angle

此新功能主要与 CSS 类型有关,但新的 API 也使变量的 TypeScript(或 Flow)类型更强大。

如示例所示,在使用stylex.createTheme创建主题时,可以使用泛型类型参数来约束变量可以取的值。

ESlint 插件

新的 sort-keys 规则

我们在 StyleX ESlint 插件中添加了一个新的 sort-keys 规则。此规则是一个风格规则,用于强制对 StyleX 样式的键采用一致的顺序。

感谢 nedjulius

valid-styles 规则的 propLimits 改进

valid-styles 规则已得到改进,允许更具表达力的“属性限制”。

其他

  • ESlint 'valid-styles' 规则现在允许在动态样式中使用用 stylex.defineVars 创建的变量作为键。
  • 实验性 stylex.include API 的错误修复
  • 修复了 stylex.createTheme 的调试 className 生成
  • 不再从 0 值中删除单位
  • 编译错误修复

我们的 生态系统 页面继续随着社区项目的增长而增长。包括一个用于排序 StyleX 样式的 Prettier 插件

·阅读 2 分钟
Naman Goel

我们很高兴发布 Stylex v0.5.0,其中包含一些重大改进和修复!

新的 stylex.attrs 函数

stylex.props 函数返回一个包含 className 字符串和 style 对象的对象。某些框架可能期望 class 而不是 className,以及 style 的字符串值。

我们正在引入一个新的 stylex.attrs 函数,以便 StyleX 在更多地方都能正常工作。stylex.attrs 返回一个包含 class 字符串和 style 字符串的对象。

ESlint 插件的新 sort-keys 规则

引入了一个新的 @stylexjs/sort-keys 插件,它将按字母顺序和优先级对样式进行排序。这将使媒体查询顺序更易预测。

感谢 @nedjulius

StyleX Babel 插件的新 aliases 选项

可以使用新的 aliases 字段配置 StyleX 以解析可能在您的 tsconfig 文件中设置的自定义别名。**注意**:StyleX 目前需要使用别名的绝对路径进行配置。

感谢 @rayan1810

新的 Esbuild 插件

一个新的官方 Esbuild 插件已作为 @stylexjs/esbuild-plugin 引入。

感谢 @nedjulius

其他增强功能

  • 传递给 StyleX Babel 插件的配置选项现在将进行验证。
  • @stylexjs/stylex 现在除了 CommonJS 导出之外,还具有 ESM 导出。
  • ESLint valid-styles 规则将在使用空字符串作为字符串值时进行捕获。

错误修复

  • 一些以前导致类型和 lint 错误的 CSS 属性现在将被接受。
  • 使用变量进行 opacity 将不再导致类型错误。
  • stylex.defineVars 中使用 stylex.keyframes 现在将正常工作
  • runtimeInjection 将被正确处理
  • defineVars 中变量的值设置为动态样式现在将正常工作。
  • 在 CSS 函数中使用 0px 将不再简化为无单位的 0,因为这在某些情况下不起作用。
  • 将保留 CSS 运算符周围的空格。

除此之外,我们还在网站上添加了一个“生态系统”页面,以突出显示围绕 StyleX 的各种社区项目。

·阅读 2 分钟
Naman Goel

三周前,我们开源了 StyleX。从那时起,我们一直在努力修复错误和改进。以下是一些亮点

增强功能

  • 编译后生成的 JavaScript 量进一步减少。
  • 为 ESLint 插件添加了一些以前缺少的 CSS 属性的支持。
  • 添加了在 stylex.keyframes 中使用变量的支持。
  • 从生产运行时中删除了样式注入代码,从而使运行时的大小减少了 50% 以上。
  • 为 Rollup 插件添加了 Flow 和 TypeScript 类型。
  • 添加了在所有捆绑器插件中使用 CSS 层的选项。
  • TypeScript 现在将自动完成样式属性名称。
  • 捆绑器插件现在将跳过不包含 StyleX 的文件,从而加快构建速度。

错误修复

  • 修复了 ESLint 插件有时无法解析用于媒体查询和伪类的本地常量的问题。
  • 解决了在开发模式下样式的运行时注入有时会失败的问题。
  • 解决了在开发过程中运行时注入的样式有时会遇到特异性冲突的问题。
  • Theme 的 TypeScript 类型现在将在为错误的 VarGroup 应用主题时正确抛出错误。

除此之外,我们还对类型和文档进行了其他改进。我要感谢所有贡献者提交的请求请求。♥️

新年快乐!

·阅读时间: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 的每个主要外部和内部产品(包括 Facebook、WhatsApp、Instagram、Workplace 和 Threads)样式化 React 组件。它改变了我们编写组件的方式,并解决了我们的团队之前在无法封装和扩展其样式化组件方面遇到的问题。

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

开源

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

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

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