目录
为什么需要另一个CIJ库?
最小的运行时
原子输出
如何使用它
定义样式
解析样式
组合样式
总结
致谢
链接
首页 web前端 css教程 样式9:构建时间CSS-In-JS

样式9:构建时间CSS-In-JS

Apr 03, 2025 am 09:28 AM

style9: build-time CSS-in-JS

Facebook去年四月发布了其重大改版。这是一个雄心勃勃的项目,是对一个拥有海量用户的庞大网站的重建。为了实现这一目标,他们使用了自己创建并开源的几项技术,例如React、GraphQL、Relay和一个名为stylex的新CSS-in-JS库。

这个新库是Facebook内部使用的,但他们分享了足够的信息,使得开源实现style9成为可能。

为什么需要另一个CIJ库?

现已存在大量的CSS-in-JS (CIJ)库,因此可能不清楚为什么还需要另一个库。正如Christopher Chedeau所阐述的那样,style9具有与所有其他CIJ解决方案相同的好处,包括作用域选择器、死代码消除、确定性解析以及在CSS和JavaScript之间共享值的能力。

然而,有一些方面使style9独树一帜。

最小的运行时

尽管样式是在JavaScript中定义的,但它们由编译器提取到常规的CSS文件中。这意味着最终的JavaScript文件中不会包含任何样式。唯一剩下的就是最终的类名,最小的运行时将有条件地应用这些类名,就像您通常所做的那样。这将导致代码包更小、内存使用减少以及渲染速度更快。

由于值是在编译时提取的,因此无法使用真正动态的值。幸运的是,这些值并不常见,而且由于它们是唯一的,因此不会因为内联定义而受到影响。更常见的是有条件地应用样式,当然这是支持的。多亏了babel的path.evaluate,局部常量和数学表达式也是支持的。

原子输出

由于style9的工作方式,每个属性声明都可以成为具有单个属性的独立类。例如,如果我们在代码中多个地方使用opacity: 0,它在生成的CSS中只会存在一次。这样做的好处是,CSS文件的大小随着唯一声明的数量而增长,而不是随着声明的总数而增长。由于大多数属性被多次使用,这可以导致CSS文件大幅缩小。例如,Facebook旧的首页使用了413 KB的gzip压缩CSS。改版后,所有页面的CSS大小为74 KB。同样,较小的文件大小会导致更好的性能。

有些人可能会抱怨这一点,认为生成的类名不是语义化的,它们是不透明的,并且忽略了级联。这是真的。我们将CSS视为编译目标。但这是有充分理由的。通过质疑以前被认为最佳的实践,我们可以改善用户和开发人员的体验。

此外,style9还有许多其他强大的功能,包括:使用TypeScript进行类型化样式、消除未使用样式、使用JavaScript变量的能力以及对媒体查询、伪选择器和关键帧的支持。

如何使用它

首先,像往常一样安装它:

<code>npm install style9</code>
登录后复制

style9有针对Rollup、Webpack、Gatsby和Next.js的插件,它们都基于Babel插件。关于如何使用它们的说明可在存储库中找到。在这里,我们将使用webpack插件。

<code>const Style9Plugin = require('style9/webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  module: {
    rules: [
      // 这将转换style9调用
      {
        test: /\.(tsx|ts|js|mjs|jsx)$/,
        use: Style9Plugin.loader
      },
      // 这是正常的Webpack CSS提取的一部分
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    // 这将对最终的CSS文件中的声明进行排序并删除重复的声明
    new Style9Plugin(),
    // 这是正常的Webpack CSS提取的一部分
    new MiniCssExtractPlugin()
  ]
};</code>
登录后复制

定义样式

创建样式的语法与其他库非常相似。我们首先使用样式对象调用style9.create:

<code>import style9 from 'style9';

const styles = style9.create({
  button: {
    padding: 0,
    color: 'rebeccapurple'
  },
  padding: {
    padding: 12
  },
  icon: {
    width: 24,
    height: 24
  }
});</code>
登录后复制

因为所有声明都将产生原子类,所以诸如flex: 1和background: blue之类的简写将不起作用,因为它们设置了多个属性。可以展开的属性,例如padding、margin、overflow等,将自动转换为它们的完整形式。如果您使用TypeScript,则在使用不受支持的属性时会收到错误。

解析样式

要生成类名,我们现在可以调用style9.create返回的函数。它接受我们要使用的样式键作为参数:

<code>const className = styles('button');</code>
登录后复制

该函数的工作方式是这样的:右侧的样式优先,并将与左侧的样式合并,就像Object.assign一样。以下将产生一个填充为12px且文本为rebeccapurple的元素。

<code>const className = styles('button', 'padding');</code>
登录后复制

我们可以使用以下任何格式有条件地应用样式:

<code>// 逻辑与
styles('button', hasPadding && 'padding');
// 三元运算符
styles('button', isGreen ? 'green' : 'red');
// 布尔对象
styles({
  button: true,
  green: isGreen,
  padding: hasPadding
});</code>
登录后复制

这些函数调用将在编译期间被删除,并替换为直接的字符串连接。上面代码中的第一行将被替换为类似'c1r9f2e5 ' hasPadding ? 'cu2kwdz ' : ''的内容。没有留下运行时代码。

组合样式

我们可以通过使用属性名访问样式对象并将其传递给style9来扩展样式对象。

<code>const styles = style9.create({ blue: { color: 'blue; } });
const otherStyles = style9.create({ red: { color: 'red; } });

// 将为红色
const className = style9(styles.blue, otherStyles.red);</code>
登录后复制

就像函数调用一样,右侧的样式优先。但是,在这种情况下,类名不能静态解析。相反,属性值将被类替换,并在运行时连接。属性像以前一样添加到CSS文件中。

总结

CSS-in-JS 的好处是真实存在的。也就是说,当我们将样式嵌入到代码中时,会产生性能成本。通过在构建时提取值,我们可以同时获得两全其美的效果。我们可以从将样式与标记放在一起以及使用现有的JavaScript基础设施中获益,同时还可以生成最佳样式表。

如果style9听起来很有趣,请查看存储库并试用一下。如果您有任何疑问,请随时提出问题或联系我们。

致谢

感谢Giuseppe Gurgone 对style-sheet和dss的工作,感谢Nicolas Gallagher对react-native-web的工作,感谢Satyajit Sahoo和Callstack的全体成员对linaria的工作,感谢Christopher Chedeau、Sebastian McKenzie、Frank Yan、Ashley Watkins、Naman Goel以及在Facebook上从事stylex工作的其他所有人愿意公开分享他们的经验教训。以及任何其他我错过的其他人。

链接

  • johanholmerin/style9
  • 使用React、GraphQL和Relay构建新的facebook.com – 2019年4月30日
  • 使用React和Relay构建新的Facebook | Frank Yan – 2019年10月30日
  • 新的Facebook.com的技术栈重建 – 2020年5月8日
  • johanholmerin/style9-components.macro:style9的Styled Components API – 实验性

以上是样式9:构建时间CSS-In-JS的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

VUE 3 VUE 3 Apr 02, 2025 pm 06:32 PM

它的出局!恭喜Vue团队完成了完成,我知道这是一项巨大的努力,而且很长时间。所有新文档也是如此。

使用Redwood.js和Fauna构建以太坊应用 使用Redwood.js和Fauna构建以太坊应用 Mar 28, 2025 am 09:18 AM

随着最近比特币价格超过20k美元的攀升,最近打破了3万美元,我认为值得深入研究创建以太坊

您可以从浏览器获得有效的CSS属性值吗? 您可以从浏览器获得有效的CSS属性值吗? Apr 02, 2025 pm 06:17 PM

我有人写了这个非常合法的问题。 Lea只是在博客上介绍了如何从浏览器中获得有效的CSS属性。那样的是这样。

带有粘性定位的堆叠卡和一点点的杂物 带有粘性定位的堆叠卡和一点点的杂物 Apr 03, 2025 am 10:30 AM

前几天,我发现了科里·金尼文(Corey Ginnivan)网站上的这一点,当您滚动时,彼此之间的卡片堆放集。

在CI/CD上有点 在CI/CD上有点 Apr 02, 2025 pm 06:21 PM

我说的“网站”比“移动应用程序”更合适,但我喜欢Max Lynch的框架:

比较浏览器的响应式设计 比较浏览器的响应式设计 Apr 02, 2025 pm 06:25 PM

这些桌面应用程序中有许多目标是同时在不同的维度上显示您的网站。因此,例如,您可以写作

在WordPress块编辑器中使用Markdown和本地化 在WordPress块编辑器中使用Markdown和本地化 Apr 02, 2025 am 04:27 AM

如果我们需要直接在WordPress编辑器中向用户显示文档,那么最佳方法是什么?

为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? 为什么Flex布局中的紫色斜线区域会被误认为是'溢出空间”? Apr 05, 2025 pm 05:51 PM

关于Flex布局中紫色斜线区域的疑问在使用Flex布局时,你可能会遇到一些令人困惑的现象,比如在开发者工具(d...

See all articles