site logo

Marico's space

前端 SEO 工具哪家强?2026 年 JS 项目 SEO 检查工具实战对比|两周踩坑总结

前端技术 2026-04-26 21:30:04 17

按语:说实话,这篇文章读到一半我就感觉被暴击了——做技术博客这么久,SEO 检查从来没进过 CI/CD(持续集成/持续部署)流水线,全凭感觉和玄学。直到被产品经理指着流量报表质问,才意识到我们连最基本的关键词分布都没做验证。作者用两周时间同时跑两个工具跑出了一个 200 页的内容站,这种实操经验比任何官方文档都有说服力。翻译过程中我结合自己踩过的坑做了不少本地化调整,特别是把 Gatsby 换成了国内更常见的 Vue/Nuxt 场景,希望对写技术博客或者做内容站的朋友们有点帮助。

说实话,做技术博客这么多年,我踩过不少 SEO 的坑。最离谱的一次是我们花了半个迭代搭了个博客平台,结果有同事偶然发现——我们的核心关键词居然一个 H2 都没进。Google 知道,流量知道,就我们自己不知道。因为压根没有在任何流程里加 SEO 检查环节。

这件事逼着我花了两个礼拜研究 JavaScript 生态里的 SEO 工具。最后我直接在手上一个 200 页的 Nuxt 内容站里同时跑了两个工具,用的是真实数据,测的是生产环境。这篇文章就是我的真实感受——包括它们各自的软肋。

核心问题:大多数 JS 项目根本没有 SEO 验证

如果你用 Next.js、Remix 或者 Nuxt 开发,大概率在每次合并代码前都会跑 TypeScript 检查、代码 lint、单元测试。但 SEO 呢?通常是手动看两眼,甚至完全不看——直到 Google 已经索引了一个半成品页面才发现问题。

SEO 出问题通常在两个完全不同的阶段:

  1. 构建之前 —— 内容本身:核心关键词有没有进 Title?至少进了一个 H2 吗?图片的 Alt 属性里有没有?
  2. 构建之后 —— HTML 结构:页面有没有 canonical 标签?Title 字符数是不是在 50–60 之间?所有图片都带 Alt 属性了吗?

两个完全不同的问题,需要两个完全不同的工具。让我一个个说。

工具一:构建前检查内容质量

这里推荐 @power-seo/content-analysis。(先声明:我是这个库的维护者之一——所以你懂的,我的热情可能带点主观色彩,但好处是我对它的内部实现理解得比较透彻。)

这是一个 TypeScript 优先的库,能对你的内容字段跑 13 项页面级检查——包括 title、meta description、核心关键词、正文 HTML、slug、图片 Alt 属性——然后返回一个结构化的评分报告。

它可以在 Next.js 服务端组件、Remix loader、Vercel Edge Functions,还有普通的 Node.js 脚本里跑。不依赖 DOM,不依赖浏览器 API。

安装:

npm i @power-seo/content-analysis

一个真实的 MDX 博客预合并 CI(持续集成)门禁脚本:

// scripts/seo-gate.ts
import { analyzeContent } from '@power-seo/content-analysis';
import { readFileSync } from 'fs';
import matter from 'gray-matter';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';

async function runSeoGate(mdxFilePath: string): Promise<void> {
  const raw = readFileSync(mdxFilePath, 'utf-8');
  const { data: frontmatter, content: mdContent } = matter(raw);

  const vfile = await unified()
    .use(remarkParse)
    .use(remarkRehype)
    .use(rehypeStringify)
    .process(mdContent);

  const result = analyzeContent({
    title: (frontmatter.title as string) ?? '',
    metaDescription: (frontmatter.description as string) ?? '',
    focusKeyphrase: (frontmatter.focusKeyphrase as string) ?? '',
    content: String(vfile),
    slug: (frontmatter.slug as string) ?? '',
  });

  const failures = result.results.filter((r) => r.status === 'poor');
  if (failures.length > 0) {
    console.error('SEO gate failed:');
    failures.forEach((f) => console.error('  X', f.description));
    process.exit(1);
  }

  console.log(`SEO gate passed - Score: ${result.score}/${result.maxScore}`);
}
runSeoGate(process.argv[2]!);

实际检查内容包括: 关键词密度(0.5–2.5%)、关键词是否在开头段落、关键词是否至少出现在一个 H2 里、关键词是否在 slug 里、图片 Alt 覆盖率、Title 长度、meta description 长度等等。

在 GitHub Actions 里,PR 合并前跑这个:

# .github/workflows/seo-check.yml
name: SEO gate
run: npx ts-node scripts/seo-gate.ts content/posts/my-new-post.mdx

如果关键词在文章里分布不对,直接阻断构建。想再发一篇 Google 完全忽略的文章?没门了。

它的局限: 自定义规则加不了,这 13 项检查是固定的。如果你需要文章必须提到我们产品名称这种逻辑,对不起,这个库不负责,得自己写。

工具二:构建后审计 HTML 结构

seo-analyzer 是另一种思路。它是个基于规则的 HTML 检查器——CLI 优先,可以跑文件、文件夹、URL,或者原始 HTML 字符串。它有 6 个内置规则,同时支持完全自定义的异步规则函数。

杀手级功能是 inputFolders()。构建完成后对着你的 /public 目录跑一遍,它自动扫描所有 HTML 文件。

安装:

npm i -D seo-analyzer

批量构建后审计 Nuxt 构建产物 /public 目录:

// scripts/bulk-audit.js
const SeoAnalyzer = require('seo-analyzer');
const { writeFileSync } = require('fs');

new SeoAnalyzer()
  .inputFolders(['public'])
  .ignoreFolders(['public/404', 'public/_nuxt'])
  .addRule('titleLengthRule', { min: 50, max: 60 })
  .addRule('imgTagWithAltAttributeRule')
  .addRule('metaBaseRule', { list: ['description', 'viewport'] })
  .addRule('canonicalLinkRule')
  .addRule('aTagWithRelAttributeRule')
  .outputJson((json) => {
    writeFileSync('seo-report.json', json);
    console.log('Report written to seo-report.json');
  })
  .run();

或者完全不用写脚本,直接用 CLI:

seo-analyzer -fl public

一条命令扫描 200 个 HTML 文件,暴露所有结构性问题。部署后 CI 流程里用这个,绝杀。

自定义规则才是 seo-analyzer 真正发挥作用的地方。假设你需要每个页面都有 WebPage JSON-LD 结构化数据:

const jsonLdRule = async (dom) => {
  const scripts = dom.window.document.querySelectorAll(
    'script[type="application/ld+json"]'
  );
  const hasWebPage = Array.from(scripts).some((s) => {
    try {
      return JSON.parse(s.textContent)['@type'] === 'WebPage';
    } catch {
      return false;
    }
  });
  return hasWebPage ? [] : ['Missing WebPage JSON-LD structured data'];
};

new SeoAnalyzer()
  .inputFolders(['public'])
  .addRule(jsonLdRule)
  .outputObject(console.log)
  .run();

8 行代码搞定,不需要升级任何库版本。

它的局限: 没有核心关键词概念,只检查结构——Title 长度、canonical 是否存在、Meta 标签有没有——但完全无法告诉你关键词有没有出现在 H2 或者开头段落里。而且它是 CommonJS(同步模块规范),完全没有 TypeScript 类型。

性能:数字说话

测试环境:MacBook Pro M2,Node.js 20:

  • @power-seo/content-analysis:每次检查 2–5 毫秒(同步,内存操作)。CMS 编辑器里每次按键都跑一遍都没问题。
  • seo-analyzer 用 inputHTMLString():每次检查 40–60 毫秒(异步,DOM 解析 + 规则执行)。
  • seo-analyzer 扫描 200 个 HTML 文件:总计 8–12 秒——CI 里跑没问题,但想做实时反馈就洗洗睡了。

包体积也很重要。@power-seo/content-analysis 压缩后大概 60KB,是 ESM 模块,支持 tree-shaking,边缘运行时安全。seo-analyzer 约 1MB,而且带了 Node.js 专属依赖。千万别让它进前端打包里。

我的真实收获

  • 两个库互相替代不了。它们在流水线不同阶段解决不同问题,同时跑两个不是过度设计——是完整的方案。
  • 关键词分布是大多数团队忽略的盲区。Title 和 meta 手工做对不难,但关键词有没有出现在开头段落、至少一个 H2、还有图片 Alt 里?这必须靠工具。
  • 结构检查能在规模上抓到静默失败。200 个页面里第 47 页少了 canonical 标签,手动审查根本发现不了。用 seo-analyzer -fl public,10 秒就给你找出来。
  • TypeScript 支持比你想象的更重要。如果项目是严格 TypeScript 体系,seo-analyzer 缺类型意味着每次调用都走 any,摩擦积累得很快。

如果想了解关键词评分这套思路,Power SEO 生态(包括 @power-seo/content-analysis)都是开源的:Power SEO

你们团队是什么配置?

我跟不少团队聊过,大多数要么 CI 里完全没有 SEO 检查,要么只在部署后扫一下 URL。真正在合并前跑内容门禁的,少之又少。

你们的 SEO 验证流水线是怎么设计的? CI 里跑?编辑器里跑?还是两者都没有,全靠上线后去 Search Console(谷歌搜索控制台)看数据亡羊补牢?我很好奇关键词级别的验证是不是团队真正需要的,还是结构级检查对大多数场景就够用了。

评论区聊聊你们现在的配置——我是真的想了解。