oekazuma/svelte-vitals

GitHub: oekazuma/svelte-vitals

svelte-vitals 是一款面向 SvelteKit 的静态 SEO 检查器,在 CI/PR 阶段无需浏览器即可分析路由的 head 元数据完整性。

Stars: 0 | Forks: 0

# svelte-vitals [![CI](https://github.com/oekazuma/svelte-vitals/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/oekazuma/svelte-vitals/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/svelte-vitals)](https://www.npmjs.com/package/svelte-vitals) [![download](https://img.shields.io/npm/dt/svelte-vitals.svg)](https://www.npmjs.com/package/svelte-vitals) [![MIT](https://img.shields.io/npm/l/svelte-vitals)](https://opensource.org/licenses/MIT) ``` npx svelte-vitals ``` ## 为什么使用 如果 ESLint 检查的是你 **代码** 的质量,那么 svelte-vitals 检查的就是你 **应用** 的质量——具体来说,即你的路由是否符合 SEO 标准。 | | 检查对象 | 何时检查 | 需要浏览器 | | ----------------------------------- | ----------------------------------- | --------------------- | --------------- | | Lighthouse / unlighthouse | 渲染结果(DOM,真实指标) | 部署后 | 是 | | eslint-plugin-svelte / svelte-check | 语法、类型、部分 a11y | 编码时 | 否 | | **svelte-vitals** | head 元数据的编写方式 | 构建前/构建期间 | **否** | 它 **不是** Lighthouse 的替代品——它是一个 **上游检查**,能在 CI 或 PR 中发现 SEO 损坏,远早于任何内容进入生产环境。而且尽管名字如此,它 **并不** 测量运行时的 Core Web Vitals (LCP / CLS / INP)。 ## 用法 在任何 SvelteKit 项目中运行它: ``` npx svelte-vitals # analyze the current directory npx svelte-vitals ./apps/web # or a specific path ``` 输出示例: ``` Svelte Vitals · SEO (static mode) Critical (1) ──────────────────────── ✗ SEO001 Missing /none src/routes/none/+page.svelte Passed (3) ──────────────────────── ✓ SEO001 <title> /blog ✓ SEO001 <title> ↯ dynamic /dynamic ✓ SEO001 <title> /static ↯ = set dynamically (verified at runtime). ``` ### 原生 Agent 输出 `svelte-vitals --reporter agent` 会生成一份 Markdown 修复文档,AI 编程 agent 可以直接据此执行操作:每个失败的发现都会列出其位置、具体的修复方案(包含代码片段)以及验收检查。 当在已知的 AI agent 框架(例如 Claude Code 会设置 `CLAUDECODE`)中运行时,它会 **自动** 被选中。你可以在任何地方通过 `SVELTE_VITALS_REPORTER=agent` 强制启用它,或者使用 `--reporter console|json` 覆盖。当被自动选中(而非明确请求)时,stderr 会打印一行提示说明如何覆盖,这样在 agent 终端中运行它的人类用户就不会对 Markdown 输出感到惊讶。 ### GitHub 集成 **内联 PR 注释(零配置)。** 在 GitHub Actions 下,svelte-vitals 会自动选择 `github` reporter,发出工作流命令,GitHub 会将这些命令转化为 PR 差异和工作流运行注释中的内联注释: ``` - run: npx svelte-vitals ``` 如果你希望在 CI 中得到不同的输出,请使用 `--reporter console|json|sarif`(或 `SVELTE_VITALS_REPORTER`)进行覆盖。 **代码扫描(安全选项卡)。** 生成 SARIF 并上传它,以将发现的问题显示为持久的代码扫描警报。上传操作需要 `security-events: write` 权限,因此请在作业(或工作流)级别授予该权限: ``` jobs: seo: runs-on: ubuntu-latest permissions: security-events: write steps: - run: npx svelte-vitals --reporter sarif > svelte-vitals.sarif continue-on-error: true - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: svelte-vitals.sarif ``` `--reporter sarif` 会将 SARIF 2.1.0 写入 stdout;将其重定向到文件以进行上传。 ### 开发覆盖层(请求驱动) 在开发过程中获取 SEO 反馈:将开发 handle 添加到 `src/hooks.server.ts`,svelte-vitals 会在你导航时分析每个页面 **渲染后** 的 `<head>`,并将当前路由的警告打印到你的开发服务器终端。它看到的是真实值,因此动态路由(`{data.title}`)会根据实际渲染的内容进行检查。 ``` // src/hooks.server.ts import { sequence } from '@sveltejs/kit/hooks'; import { svelteVitalsHandle } from '@svelte-vitals/vite/hooks'; export const handle = sequence(svelteVitalsHandle()); ``` 它仅在 `dev` 模式下运行(在生产构建中为 no-op),且从不修改响应——它只读取渲染的 HTML。覆盖范围随导航而动:只有当你访问某个路由时才会对其进行检查,并且仅在其发现的问题发生变化时才再次发出警告。 `svelteVitalsHandle` 接受插件选项中经过精简的一部分——`metaComponents` 和针对每个规则的 `rules` 覆盖(例如 `svelteVitalsHandle({ rules: { SEO008: 'off' } })`)。分析错误会被吞掉(忽略),因此工具的 bug 永远不会破坏请求;在调试时可以设置 `SVELTE_VITALS_DEBUG` 环境变量,以便在终端中显示这些错误。 ### 退出代码 | 代码 | 含义 | | ---- | --------------------------------------------------------------- | | `0` | 无失败的发现 | | `1` | 存在严重发现 | | `2` | 执行错误(不是 SvelteKit 项目、内部错误等) | 这使得 svelte-vitals 可以用作 CI 的门控。 ## 工作原理 svelte-vitals 通过遍历布局链(`+layout.svelte` → … → `+page.svelte`)并使用官方的 `svelte/compiler` 解析 `<svelte:head>`,来解析每个路由的 **有效 `<head>`**。 其核心设计目标是 **零漏报**。SvelteKit 的元数据通常是动态的,因此每个标签都在两个独立的维度上被检测: - **存在性** — `own`(由路由设置)、`inherited`(来自父布局)或 `none` - **取值** — `static`(字面量)、`dynamic`(`{data.title}` — 值仅在运行时可知)或 `absent`(存在但为空) 像 `<title>{data.title}` 这样的动态标题——这是 SvelteKit 中最常见且正确的模式——**永远不会** 被标记为缺失。它会以 `↯` 标记通过。只有真正缺失(`none`)或为空(`absent`)的元数据才会被扣分。 ## 路线图 该项目沿着两个轴线推进:**模式成熟度** 和 **类别覆盖率**。SEO 是第一个类别;随后会有更多类别。 **已发布** - **静态模式 (CLI)** — 零配置的 `npx svelte-vitals`:解析每个路由的有效 ``,运行 SEO001–SEO009 规则,按路由和全站进行评分,并通过退出代码控制 CI。 - **插件模式** (`@svelte-vitals/vite`) — 搭载 `vite build` 并分析预渲染 HTML 的 ``。与库无关且精确;为成熟的站点提供真实价值。 - **Agent 与 CI 集成** — `console`、`json`、`agent`(Markdown 修复文档)、`sarif`(GitHub 代码扫描)和 `github`(内联 PR 注释)reporter。`agent` reporter 会在 AI agent 框架下自动选择;`github` 会在 GitHub Actions 下自动选择。 **即将推出** - **开发覆盖层** ([#9](https://github.com/oekazuma/svelte-vitals/issues/9)) — 通过 `transformPageChunk` 在开发时进行原地警告,以便在访问页面时能看到带有真实值的动态路由。 - **`--fix` 自动修复** ([#11](https://github.com/oekazuma/svelte-vitals/issues/11)) — 生成/修复可修复的发现(`robots.txt`、`sitemap.xml`、canonical)。 - **MCP 服务器** ([#24](https://github.com/oekazuma/svelte-vitals/issues/24)) — 将 svelte-vitals 作为 Model Context Protocol 工具公开,以便 agent 可以在其循环中直接调用它。 - **更多类别** ([#10](https://github.com/oekazuma/svelte-vitals/issues/10)) — 性能、可访问性和升级检查,最终在 `1.0` 版本中汇总为一份综合健康报告。 查看设计文档以了解完整的愿景。 ## 包 | Package | 描述 | | ---------------------------------------- | ----------------------------------------------------------- | | [`svelte-vitals`](./packages/cli) | CLI + 静态模式 (`npx svelte-vitals`) | | [`@svelte-vitals/core`](./packages/core) | 与运行时无关的核心:类型、规则引擎、评分器、reporter | | [`@svelte-vitals/vite`](./packages/vite) | 插件模式(构建时):分析预渲染的 `` | ## 开发 这是一个 pnpm-workspaces monorepo (TypeScript / ESM)。 ``` pnpm install pnpm build # build all packages (tsup) pnpm test # vitest pnpm typecheck # tsc --noEmit pnpm lint # prettier --check + eslint ``` 版本发布通过 [Changesets](https://github.com/changesets/changesets) 管理:运行 `pnpm changeset` 来描述你的更改,随后合并到 `main` 分支会自动打开发布 PR。 ## 许可证 [MIT](./LICENSE.md) © [Kazuma Oe](https://github.com/oekazuma)
标签:MITM代理, SEO检查, SvelteKit, 云安全监控, 图数据库, 自动化攻击, 静态分析