在 Vue 或 Svelte 项目上使用 StyleX
我近期沉迷于 Atomic CSS-in-JS。本博客目前使用 Panda CSS 生成样式,但通过 PostCSS 使用 Panda CSS 会获得非常稀烂的开发体验,我也不太喜欢使用 CLI Mode,故将目光转移至 Facebook 的 StyleX。本文将会介绍一种在 Vue 或 Svelte 项目上使用 StyleX 的方法。
StyleX SWC Plugin
StyleX SWC Plugin 是一个非官方的高性能 StyleX 编译器,基于 NAPI-RS、SWC 插件和适用于 StyleX 的完整 CSS 解析器。
选择这个插件的一方面是性能。StyleX 的官方编译器使用了 Babel 编写。Babel 的历史悠久且插件生态强大,但相较于当今用 Rust 编写的 SWC 和 OXC,用 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.js 或 rspack.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。
