@animus-ui/vite-plugin (英语)
Vite 的静态 CSS 提取插件 。 变换 @animus-ui/system 构建器链入建时为静态CSS——零运行时风格注入.
安装
npm install @animus-ui/vite-plugin @animus-ui/system
设置
// vite.config.ts
import { animusExtract } from '@animus-ui/vite-plugin';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react(), animusExtract({ system: './src/ds.ts' })],
});
这个 system 选项指向导出您已建系统实例的文件。 插件在子进程中加载此文件,以序列化Rust提取管的道具配置和主题数据.
TypeScript apps 获得插件的虚拟模块(virtual:animus/styles.css, (中文(简体) ), virtual:animus/font-preloads键入 /// <reference types="@animus-ui/vite-plugin/client" /> 或者说 "types": ["@animus-ui/vite-plugin/client"] 内 tsconfig.json。 。 。 .
它会做什么
- 构建时间: 分析所有导入文件
@animus-ui/system,将静态样式提取到 CSS 中@layer命令 - Dev 服务器: 启动时运行提取, 将结果保存在内存, 通过虚拟模块服务 CSS
- 变换: 决定
__TRANSFORM__使用您系统命名的变换函数的占位符 - 全局样式: 从导出时输出全局样式( 重置, 底部)
createGlobalStyles()配置
外观花纹
可选的 恢复第一次涂料前的持久颜色模式,所以是阴暗的
页面从不闪出一个光框——带有 零运行时间和真实的 CSP 故事。 。 。 .
修复是生成的无依赖的内接片段(不是组件,
和它的 script-src 散列在构建时从
生成精确字节 。 运行时主题切换器必须在其中选择
unsafe-inline 和手持的散货, 将沉入泥潭; 这里的文物IS
散列源,所以一个主题编辑 永远不能拖出一个被扭曲的散列
更改它授权的代码 .
创造文物 在您的虚拟配置中 ——它正在建设工具,没有
下级 src/ 可能导入 :
// vite.config.ts
import { createAppearanceBootstrap } from '@animus-ui/system/bootstrap';
import { animusExtract } from '@animus-ui/vite-plugin';
import { defineConfig } from 'vite';
import { theme } from './src/ds';
const appearanceBootstrap = createAppearanceBootstrap(theme);
export default defineConfig({
plugins: [animusExtract({ system: './src/ds.ts', appearanceBootstrap })],
});
该插件是 仅交付: 它会注射 artifact.code 逐字记录作为内线
<script data-animus-bootstrap> 内 <head>,在字符集和取景端之后
metas(所以字符集保留在前1024字节之内),领先于每个字节
样式表引用,并解释不外观语义。 关闭选项
已建的 HTML 是之前的字节.
内容-安全政策
文物的第二块地, cspHash,授权内置脚本。 两项规则:
-
建造时从文物中取出.
createAppearanceBootstrap返回它刚刚生成的确切字节的散列。 重新命名颜色模式或 变化storageKey改变这些字节,从而改变散列——a 拼接文件中的手抄字 静悄悄地变成僵硬的花草 指被屏蔽的脚本和错误模式的闪光. -
单引用它
script-src。 。 。 . 该值已返回准备使用 :Content-Security-Policy: script-src 'sha256-…'未引用,
sha256-…描述为 东道主 源,没有匹配,默默 未授权脚本 .
永远不要回头 unsafe-inline,并且从不使用构建时常无序.
// Build the header from the artifact — never from a copied string.
// The hash is single-quoted in the source list, per the rule above.
const csp = `script-src 'self' '${appearanceBootstrap.cspHash}'`;
Next.js 故意不自动: CSP 非ce 需要请求时间控制
捆绑者没有,所以应用程序设置 artifact.code 本身和
用品或 cspHash 或每个要求的无。 已工作的 App 路由器和页面
路由器实例存在于
@animus-ui/next-plugin 读取。 。 。 .
字体预装
声明字体面相 preload: true 获得一个
<link rel="preload" as="font" crossorigin data-animus-preload> 内 <head>, (中文(简体) ),
在字符集和取景器 metas 之后,并在每个样式表链接之前。 内容
href 是样式表的 URL url() 负载:一建筑物中的散列资产,
dev 服务器的 URL 正在开发中 。 根相对或绝对的 URL
index.html 已经预加载没有第二次预加载。 一个建筑警告,命名
hTML 页面,当完成的页面通过另一页预装同一文件时
标记: 在页面中为一个 asset() 文件,或一个插件从
a 一个 index.html 钩子在Animus后跑.
fontPreloads 选择预加载的面孔取而代之 preload
旗子,是一个只让系统一些面孔的应用程序。 一个姓
选择家庭的每一个面; { family, weight?, style? } 选择
其申报重量包含的面相 weight (可变面相范围)
'100 900' 他们的风格是: style (单位:千美元)'normal' 何时
删去:
animusExtract({
system: './src/ds.ts',
fontPreloads: [
{ family: 'Apercu', weight: 400 },
{ family: 'Apercu', weight: 'bold' },
{ family: 'Suisse', weight: 700 },
],
});
一个入口 fetchpriority (单位:千美元)'high', (中文(简体) ), 'low' 或者说 'auto')写在
预装它所选择的面孔, 在 index.html 内
virtual:animus/font-preloads; 文件所选择的多个条目带有
最强的 预装与关键 CSS 和
Java 脚本, 所以给 'high' 仅面向面部 第一张屏幕画有:
fontPreloads: [{ family: 'Apercu', weight: 400, fetchpriority: 'high' }],
[] 预装无。 没有面相匹配的报表条目
animus.style.font-preload-unmatched; 畸形的, 如重
范围,报告 animus.style.font-preload-invalid。 。 。 .
预装与关键 CSS 和 JavaScript 相竞争,所以
预装 WOFF2 并只装入第一个屏幕所需的面孔: 一个大型的 TrueType
文件可以在缓慢的链接上将第一次油漆延迟数秒。 预装文件
不是WOFF2或WOFF,或是一个 asset() 超过150 KB的文档,报告
animus.style.font-face-preload-costly。 。 。 .
拆分样式表
stylesheets: 'split' 将样式表构建为三个文件而不是一个文件,
单页的相接片,按顺序排列:
- 基础:主题变量和颜色模式,
@property登记, 财务报告和审定财务报表anm-global(重设,@font-face键框),带有任意quarantine工作表; - 组件 :
anm-base, (中文(简体) ),anm-variants, (中文(简体) ),anm-compounds, (中文(简体) ),anm-states· ; - 公用事业:
anm-system, (中文(简体) ),anm-custom。 。 。 .
每个页面都按维特将单张工作表放在哪里的顺序链接它们
在应用程序自己的CSS中,作为普通的渲染屏蔽样式表:app CSS
与它捆绑在一起 在三个文件之前或之后保留它的位置。 他们握住
单页按顺序排列,所以级联不变; Vite
将每个文件自行修改,使其字节与
结束每个文件的新行。 他们的URL是维特自己给的
链接,通过 base 财务报告和审定财务报表 experimental.renderBuiltUrl。 。 。 .
每个文件都按其内容命名,因此浏览器保留其缓存副本
单文件编辑出处: 编辑到组件样式仅更改
组件文件。 三个文件压缩得略差于一个(大约
大型应用上增加0.1%的gzip.
animusExtract({ system: './src/ds.ts', stylesheets: 'split' });
分块构建需要从 HTML 构建的页面链接样式表,
链接的去处:没有页面的,或者其样式表只是懒惰的
负载, 失败 。 dev 服务器保存一个工作表. 'single' (默认)
是捆绑进口的一页.
第三方样式表
图书馆的平面 CSS 外部任意 @layer 击败每个Animus层. 与
quarantine, (中文(简体) ), @animus-ui/layergate 装入
anm-vendor在Animus的下面一层 所以Animus的风格就赢了
animus 无设置时, 库仍然适用 :
bun add -D @animus-ui/layergate
animusExtract({
system: './src/ds.ts',
quarantine: {
sheets: ['react-grid-layout/css/styles.css'], // delivered ahead of Animus's own CSS
dependencies: ['react-datepicker'], // CSS these packages' modules import
optOut: [], // exact files whose own rules stay unlayered
},
});
sheets 来到Animus自己的风格表的首端,无论它在哪里
导入,所以不需要额外导入 。 他们的字体和图像保存
解析, 包含工程根外的文件 .
!important 宣言和动画仍然获胜,并被报道。 应用
CSS 保持自身规则的不高; 在导入供应商文件时, 该文件
是分层的。 支助科 模块单独存在.
磁共振
Animus 读每个 .mdx * 作为其JSX:进口、出口、,
标记、道具和 {expressions}它不需要MDX编译器。 组件标记
名称,或您的供应商之一的下图# x 你的头,数
现予公布。 马克倒数和代码例子 使什么也没有.
MDX 生成组件; 它宣布没有样式 。 Animus报告任何参考资料
到它的建筑者在一个 .mdx 文件为 SOURCE_MDX_STYLE_DECLARATION,则a
严格建设失败。 包括从 @animus-ui/system, (中文(简体) ),
以及任何以建造方法命名的成员(styles, (中文(简体) ), variant, (中文(简体) ),
compound, (中文(简体) ), states, (中文(简体) ), system, (中文(简体) ), props, (中文(简体) ), extend, (中文(简体) ), asElement, (中文(简体) ),
asComponent, (中文(简体) ), asClass),读取,调用或分解. 这么说吧 {Box.styles}
也报告。 宣布组件为 .ts 或者说 .tsx 文档并导入它们.
重要
- 执行 没有 添加反应解析别名到
vite.config.ts他们打破了提炼变压管道 - 在系统配置改变后,重新启动dev服务器(子进程运行于
buildStart(中文(简体) ) - 运行
bun run clean:light如果样式看起来僵化( 清晰).vite缓存) - 虚拟模块 ids 发布合同, Vite 给出第一个
resolveId编号 :load回答一个 id 到整个配置, 因此一个 Vite 配置中的两个插件实例 共享一个桥和一个样式表 —— 第二例的模块解析到第一个的 。 平分键只分离出独立构建的共享文档的捆绑.
许可证
麻省理工学院