Vext JSCSS
目录导航
何时使用 JSCSS
Vext JSCSS 会在构建期把 TypeScript 对象转换为 CSS class。组件需要有名字的 variants、语义化 CSS variables 或嵌套规则,同时希望规则在构建期抽取为 CSS 时,可以使用它。客户端仍可能执行 class-name/variant 辅助函数,但不依赖第三方样式 runtime 注入 CSS。
按需求选择最小的工具:
Vext 不会编译 Sass 或 SCSS 源文件。如果团队继续使用 Sass,请先在交给 Vext 前编译为 CSS。JSCSS 不是 Sass 的替代品;它是 Vext 内置的、面向组件的类型化生成 CSS 路径。
跑通第一个组件样式
在已完成全栈快速开始的应用中,在 *.style.ts 定义有名字的 recipe,再在 React 的 className 中调用。下面补齐样式、组件、页面与路由;保留默认开启的 JSCSS 即可。
1. 定义按钮 recipe
创建 src/frontend/styles/button.style.ts。
recipe() 的 base 和 variants 接收的是 rule object。style() 已经返回 class-name 字符串,因此不要在 recipe 内写成 base: style({ ... }) 或 primary: style({ ... })。给 recipe 设置 name,在检查 HTML 或 CSS 时就能识别生成的 class。
2. 在 React 组件中使用 recipe
创建 src/frontend/components/Button.tsx。
button({ intent: "primary" }) 会返回 base class 和匹配的 variant class。因为示例设置了默认 variant,所以没有选择时调用 button() 也会得到 primary 按钮。
3. 从页面渲染它
创建页面和明确的 HTTP 路由。默认 NodeNext 模板的相对 TypeScript 导入使用 .js 扩展名,框架 alias 则沿用模板已有映射。
/settings 应显示 danger 样式按钮;这里只演示外观,按钮没有绑定删除行为。
构建后如何进入浏览器
执行正常的生产构建:
Vext 默认在 frontend.root(默认 src/frontend)下扫描 **/*.style.ts、**/*.style.js 和 **/*.css.ts,在 Node 构建步骤执行匹配模块及其依赖,把规则写入生成的 JSCSS CSS;这不只限于被某个页面 import 的样式文件。生成 browser entry 引用 CSS,client asset manifest 再将其带入文档。自定义扫描范围通过 frontend.styles.jscss.files 调整。
这条路径不需要默认引入 Emotion 或 styled-components runtime。style() 或 recipe() 返回的 className 就是 React 与抽取 CSS 之间的连接。
*.style.ts 模块在 Node 构建步骤中执行,因此它应当只放声明;不要在模块顶层读取 window、document、请求数据或 server-only service。
常见样式任务
生成一个有名字的 class
只有一个 class 时使用 style():
在 CSS 期望长度的属性上,数字会转为像素值;opacity、zIndex、fontWeight 等无单位属性会保持无单位。
加入 hover 和 media 规则
嵌套 selector 使用 &,at-rule 仍放在同一个对象中:
下面替换上一段样式声明,沿用该文件已有的 style import:
在渲染期选择 variant
有限的视觉选择使用 recipe。选择名应描述组件含义(如 intent、size、state),不要照搬原始 CSS 值。
这是组件内的使用片段,isDestructive 由应用已有 props/state 提供。当前 recipe 选择以字符串键解析,未知选择值不会生成新规则;不要把运行时任意字符串当成已声明 variant,也不要假定函数提供所有 variant 名的编译期穷举校验。
CSS Variables:构建期声明与浏览器改值
createVar() 创建语义化 CSS custom-property 引用。setVar() 返回可放进 JSCSS rule 的对象;它本身不会修改浏览器 document。
上例在 panel 元素上生成初始变量声明和 var(--vext-accent, #4f46e5) 引用。若需要在 hydration 后变化,应在事件处理器或 effect 中更新该元素;下面的 element 是已取得的 panel HTMLElement,accent 从样式模块导入:
不能在样式模块顶层或 SSR render 中访问 DOM。仅设置根元素的同名变量,不会覆盖 panel 自身声明;全局主题应把变量定义移到根元素、组件通过继承读取,再用 document.documentElement.style.setProperty 改值。createVar() 返回变量描述对象;直接作为 JSCSS 属性值使用,若需要字符串形式,使用其 ref,不能把整个对象插值成 CSS 字符串。
配置怎么选
JSCSS 默认已经启用。只有在明确的交付约束下才需要改变设置:
完整字段和默认值请查看 前端配置。
排错
下一步:对比 样式与资源 了解其它受支持的样式路径;需要调节 JSCSS 抽取时阅读 前端配置。
验证示例
npm run build 成功后运行 npm start -- --port 3000,打开 /settings。核对 SSR HTML 中的 class、浏览器 CSS 文件中的对应规则,以及 danger 按钮实际颜色;只有 class 字符串存在不能证明 CSS 已加载。变量更新还需检查目标元素 computed style。构建时不匹配扫描规则的文件不会仅因运行时调用 style 就自动补出 CSS。结束后停止服务。