在 Vue 或 Svelte 项目上使用 StyleX

在 Vue 或 Svelte 项目上使用 StyleX

· 技术 · 约 1598 字

我近期沉迷于 Atomic CSS-in-JS。本博客目前使用 Panda CSS 生成样式,但通过 PostCSS 使用 Panda CSS 会获得非常稀烂的开发体验,我也不太喜欢使用 CLI Mode,故将目光转移至 Facebook 的 StyleX。本文将会介绍一种在 Vue 或 Svelte 项目上使用 StyleX 的方法。

StyleX SWC Plugin

StyleX SWC Plugin 是一个非官方的高性能 StyleX 编译器,基于 NAPI-RSSWC 插件和适用于 StyleX 的完整 CSS 解析器。

选择这个插件的一方面是性能。StyleX 的官方编译器使用了 Babel 编写。Babel 的历史悠久且插件生态强大,但相较于当今用 Rust 编写的 SWCOXC,用 JavaScript 编写的 Babel 在执行速度上仍有欠缺。而在 Next.js 上,使用 StyleX 官方编译器会导致其禁用内置的 SWC(即当 Next.js 识别到了 .babelrc 文件的创建),从而导致开发和构建性能有所下降。我算是一个「杞人忧天」的人,Panda CSS 所带来的稀烂开发体验我可不想再体验第二回,因此在效果大致相同的情况下、我会优先考虑性能更好的方案。

另一方面,StyleX 提供了官方的 Svelte 集成示例,但却没有 Vue 的集成示例。不知是我配置姿势是否有误,StyleX 的官方编译器在我的 Vue / Nuxt 项目上频繁歇菜,而 StyleX SWC Plugin 对各个框架的支持稍微好点。嗯。

配置 StyleX SWC Plugin

StyleX SWC Plugin 提供了 Unplugin 包,一包走遍各个构建工具。

配置项

我在我的项目中使用了三个配置项。以下是这三个配置项的解析:

  • rsOptions.dev:不用我多说了吧;

  • pageExtensions:需要进行转换的文件扩展名;

  • useCssPlaceholder:启用后,将会通过特定标记(如 @stylex)注入 CSS,好处 看这里

Vite

vite.config.ts 中作如下配置:

import { defineConfig } from 'vite'
import stylex from '@stylexswc/unplugin/vite'


export default defineConfig({
    plugins: [
        stylex({
            rsOptions: {
                dev: process.env.NODE_ENV === 'development'
            },
            pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'vue', 'svelte'],
            useCssPlaceholder: true
        })
    ]
})

Nuxt

nuxt.config.ts 中作如下配置:

export default defineNuxtConfig({
    modules: [
        ['@stylexswc/unplugin/nuxt', {
            rsOptions: {
                dev: process.env.NODE_ENV === 'development'
            },
            pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'vue', 'svelte'],
            useCssPlaceholder: true
        }]
    ]
})

Webpack / Rspack

webpack.config.jsrspack.config.js 中作如下配置:

module.exports = {
  plugins: [
    require('@stylexswc/unplugin/{webpack,rspack}')({
      rsOptions: {
          dev: process.env.NODE_ENV === 'development'
      },
      pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'vue', 'svelte'],
      useCssPlaceholder: true
    }),
  ],
};

在组件中使用 StyleX

通过 stylex.attrs

在之前查找 StyleX on Nuxt 的资料时,偶然在 Stack Overflow 还是 Reddit 搜到了一个自称是 StyleX 开发团队成员的回答。他在回答中介绍了 stylex.attrs 这一用法。

<template>
    <div v-bind="attrs(styles.container)"></div>
</template>

<script setup lang="ts">
import { create, attrs } from '@stylexjs/stylex';
</script>

<script lang="ts">
const styles = create({
    container: {
        display: 'flex',
        justifyContent: 'center'
    }
})
</script>
<script module lang="ts">
    import { create, attrs } from '@stylexjs/stylex'

    const styles = create({
        container: {
            display: 'flex',
            justifyContent: 'center'
        }
    })
</script>


<div {...attrs(styles.container)}></div>

通过 stylex.props

这是目前 StyleX examples 里、以及推荐使用的一个方法。

<template>
    <div :class="props(styles.container).className"></div>
</template>

<script setup lang="ts">
import { create, props } from '@stylexjs/stylex';
</script>

<script lang="ts">
const styles = create({
    container: {
        display: 'flex',
        justifyContent: 'center'
    }
})
</script>
<script module lang="ts">
    import { create, props } from '@stylexjs/stylex'

    const styles = create({
        container: {
            display: 'flex',
            justifyContent: 'center'
        }
    })
</script>


<div class={props(styles.container).className}></div>

实践案例

我的 个人主页胡思乱想博客 成功用上了 StyleX。本博客在我想好新的主题怎么写之后会同样切换至 StyleX。

喜欢的话,投喂亿下孩子吧(逃)
爱发电

💬 在 s-complex/discussions 上发表你对本文的看法。