从零搭建一个可长期维护的 Astro 技术网站

记录 Nekotail 技术空间的初始工程架构:Astro 7、四类内容集合、静态 SEO/GEO 与 Pagefind,以及为什么暂不引入前端框架。

本文目录

这个网站采用 Astro 7 静态生成:四类内容分别由独立的 Content Collections 和 Zod Schema 管理,正文在构建时直接输出为 HTML;搜索使用 Pagefind 在构建后生成索引;Lab 的交互组件通过 MDX 按需嵌入,不依赖 React、Vue 或 Svelte。

本文记录初始架构的取舍,以及后续修改视觉、内容和部署方式时需要知道的边界。验证环境为 Windows 11、Node.js 25.7.0、pnpm 12.18.0、Astro 7.4.7,验证日期 2026-11-08。这是当时的环境记录,不是最低版本要求;项目在 package.json 中声明的 Node 下限是 >=22.23.4。

为什么是 Astro

这个站点的核心内容是文章和文档,而不是需要频繁客户端交互的应用。Astro 的默认行为正好符合这个前提:

  • 页面在构建时生成静态 HTML,搜索引擎和生成式搜索系统不需要执行 JavaScript 就能读取正文。
  • 只有显式使用交互组件时才加载对应的客户端 JavaScript。
  • Markdown 与 MDX 可以直接作为内容源,不需要额外的 CMS 或数据库。
  • 内容集合与 TypeScript 类型检查可以在构建前发现字段错误。

当前没有引入 React。Astro 组件自身就可以承载少量原生 JavaScript 交互;Lab 的复杂可视化如果需要框架,再单独评估,而不是提前把整个站点绑定到某个前端框架。

四类内容,四套 Schema

内容没有统一成一个“万能文档”模型。博客、项目、知识库和 Lab 的字段含义不同,分开定义更容易校验,也更容易在未来独立演进。

集合 主要用途 关键字段
blog 技术文章与个人记录 pubDate、updatedDate、tags、draft
projects 项目展示与演进记录 status、stack、updates、featured
knowledge 分层知识库 category、parent、related、order
lab 交互实验 status、demo、repo

Schema 定义在 src/content.config.ts。新增内容时只写 Markdown/MDX 和 frontmatter,不需要改页面代码;字段不合法时 astro check 或构建会报错。

目录与职责分离

内容、页面、组件和样式各自放在固定位置:

src/
├── content/          # blog / projects / knowledge / lab
├── components/       # 按模块拆分的 Astro 组件
├── layouts/          # Base / Article / Project / Knowledge / Lab
├── pages/            # 路由与 robots.txt、rss.xml 端点
├── styles/           # tokens.css / typography.css / global.css
├── lib/              # 内容查询与 SEO 构造函数
└── content.config.ts

页面只负责路由和数据编排,布局负责内容型页面的共同结构,组件负责可复用 UI。颜色、字体、间距和页面宽度集中在 src/styles/tokens.css,后续统一调整视觉时不需要逐页查找硬编码值。

SEO 与 GEO 的落地方式

静态生成是这里最重要的 GEO 决策:正文必须出现在 HTML 中,而不是等客户端 JavaScript 执行后才出现。在此基础上,站点还实现了:

  • 每页独立的 title、description 和 canonical URL;
  • Open Graph 与 Twitter Card metadata;
  • sitemap-index.xml 与 rss.xml;
  • BlogPosting、Article、CreativeWork、Person、WebSite 和 BreadcrumbList 等 JSON-LD,只在语义匹配的页面输出;
  • 语义化标题层级、内部链接和图片 alt 的基础约束;
  • 文章 frontmatter 中的发布时间与更新时间。

robots.txt 将搜索型爬虫和训练型爬虫分开处理。搜索型爬虫始终允许;训练型爬虫由 src/config.ts 中的 robots.allowTrainingCrawlers 控制,默认允许。截至 2026-11-08,没有在 DeepSeek 官方渠道找到公开的爬虫 User-Agent 文档,因此没有把第三方猜测的 UA 写进规则,而是让通配规则覆盖未声明的情况。

需要明确:robots.txt 是访问策略声明,不是被收录、被引用或被生成式搜索引用的保证。真正的验证仍然要看服务器日志、搜索结果和实际抓取行为。

Pagefind 与中文检索

Pagefind 的索引在 astro build 之后生成,构建命令为:

pnpm build

它会将索引写入 dist/pagefind/,搜索页面在浏览器中按需加载。中文分词能力与具体构建版本有关,不能仅凭“支持多语言”就宣称中文检索效果良好。本项目使用 Pagefind 1.6.0 Extended 构建,并在 Chromium 中实测:搜索“架构”能返回博客、知识库和项目页,搜索“输入法”和“WSLg”能返回相关项目,证明中文分词和跨模块检索可用。Pagefind 会把查询拆成词并允许部分匹配,因此把短语用双引号包裹才能做精确匹配;这是索引器的行为边界,不是本站自建的语义搜索。更完整的验证记录见项目 README。

交互实验的边界

Lab 页面使用与其他模块相同的布局和设计 Token,但交互组件放在 src/components/lab/,只通过 MDX 引入。这样普通文章不需要为实验组件付出任何客户端 JavaScript 成本。

当前只提供了一个用于验证 MDX 挂载的计数组件,它不是一个真实的算法或 AI 实验。重计算场景应使用 Web Worker;是否引入 React 等框架,应由具体实验的交互复杂度决定。

当前边界与后续计划

初始架构、四类内容、静态构建、SEO 端点、Pagefind 中文检索、响应式布局和项目文档已经完成验证。当前边界主要在于内容和部署:

  1. 视觉系统已经完成第四轮调整:当前启用冰蓝白与钴蓝 Elysium,黄黑 Signal 保留为暂存 Token,停止使用大幅品牌刊头;首页改为短刊头、信号带、纸面主文卡与精简 feed,增加等高线/点云/十字背景、斜线出血标题、博客双栏和文章档案铭牌;使用手写 Nekotail wordmark 与抽象工程环图版;后续只按页面内容做局部调整;
  2. 继续补充真实文章正文和项目实现;WSLg 输入法与剪贴板两篇已经基于实测发布,其余计划文章仍保持草稿,不填充未经实测的步骤;
  3. 站点已上线 https://nekotail.moe(Cloudflare Workers 静态资源 + Custom Domain,www 301 到 apex);GitLab CI 流水线已写好,还差账号身份验证和 API Token 才能真正自动部署,之后观察真实抓取、Sitemap 和 RSS 在 CDN 后的行为。

相关阅读:本站架构概览 和 Nekotail 项目页。