能,但需构建期静态求值:css()等不可依赖运行时变量或条件分支;.css.ts未生成CSS因模块含非法导出(如函数)、未配@vanilla-extract/next-plugin、injectGlobal误用或存在动态逻辑。

能,但前提是所有样式逻辑必须在构建期静态求值完成——css()、style()、styleVariants() 的调用不能依赖运行时变量,也不能被 useState、props 或条件分支动态包裹。
为什么你的 .css.ts 文件没生成 CSS?
vanilla-extract 不是“写完就出 CSS”,它靠构建时执行 TypeScript 模块来提取规则。一旦模块导出含非法值(比如普通函数、闭包、未标记的箭头函数),就会直接报错:You can only export plain objects, arrays, strings, numbers and null/undefined.
- 常见错误:在
.css.ts里写export const Button = () => style({...})—— 函数本身无法序列化 - 更隐蔽的坑:用
process.env.NODE_ENV做条件导出,导致构建器无法确定哪些分支会被执行 - 全局样式误用
injectGlobal:它只能在客户端运行,破坏零运行时前提;应改用globalStyle
Next.js 中必须启用 @vanilla-extract/next-plugin
App Router 下不配插件,.css.ts 文件会被当成普通 TS 模块跳过编译,最终只留下 JS 导出、无 CSS 输出。
- 安装后需在
next.config.js中显式添加:plugins: ['@vanilla-extract/next-plugin'] - 插件会接管
.css.ts文件,将其转为.css静态资源,并把类名映射注入 JS bundle(仅作引用,不带运行时样式逻辑) - 若项目含动态路由或 Server Components,确保插件版本 ≥ 2.3 —— 旧版对
app/目录下嵌套路径支持不稳定
如何安全导出可复用的样式函数?
想封装 styledDiv({ background: 'blue' }) 这类 API?不能直接导出函数,得用 addFunctionSerializer 显式声明序列化逻辑。
- 在入口文件(如
styles/setup.ts)中调用:addFunctionSerializer({ id: 'styledDiv', serializer: (fn) => `styledDiv(${JSON.stringify(fn.props)})` }) - 对应函数必须挂载
__function_serializer__属性,且参数只能是 JSON-safe 类型(禁止传组件、事件处理器等) - 这种函数本质是构建期宏(macro),不是运行时高阶组件;返回值仍需是
style()产出的类名字符串
真正容易被忽略的是「静态边界」:哪怕只在一个 .css.ts 文件里写了 if (Math.random() > 0.5) { ... },整个模块都会因不可预测性被排除出 CSS 提取流程。零运行时不是配置开关,而是对代码结构的硬性约束。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











