项目概览
Mizuki 是一个基于 Astro 构建的现代化、功能丰富的静态博客模板,采用 TypeScript + Svelte + Tailwind CSS 技术栈,集成了搜索、RSS、评论、音乐播放器、追番页等大量开箱即用的能力。本页面是整个 Wiki 的入口,概括项目的定位、总体架构、技术栈、构建管线与配置体系,为深入阅读其他子主题页面提供全局视角。
⚠️ 项目状态提示:README 明确声明本项目(Mizuki)即将停止更新与维护,全面重构版本 Shirone 已发布。本 Wiki 基于仓库当前
master分支(版本9.0)的源码编写,供现有用户维护与迁移参考。参见 README.md
目的与范围(Purpose and Scope)
本页覆盖以下内容:
- 项目定位、许可证与版本信息
- 系统总体架构与分层职责(构建脚本层 → 配置层 → 内容/数据层 → 页面渲染层 → 构建产物层)
- 开发、构建、测试的完整命令管线
- 核心依赖技术栈及其用途
src/config/配置模块体系与src/data/、src/content/内容模型的总体地图- 代码/内容分离机制(外部内容仓库同步)
- 测试、部署与扩展点的概览
以下主题有意留给兄弟页面深入展开,本页仅做入口式指引("For X, see Y"):
- 各具体配置模块(导航、侧边栏、评论、音乐、Markdown、固定链接等)的逐字段说明 → 见对应配置页面
- 文章编写语法(提示框、KaTeX、Mermaid、PlantUML、Wiki Link 等)→ 见 Markdown 扩展相关页面
- 各特色页面(追番、友链、日记、相册等)的渲染实现 → 见对应页面主题
- 浏览器端加密文章的安全边界 → 见加密主题页面
概述(Overview)
Mizuki 的本质是一个 Astro 静态站点生成器项目:开发者编写 Markdown/MDX 文章与结构化数据,Astro 在构建期将其渲染为纯静态 HTML,随后用 Pagefind 生成静态搜索索引,最终产物部署到任意静态托管平台(Vercel、Netlify、GitHub Pages、Cloudflare Pages)。
它解决的核心问题是:让个人博主以"写文件"的方式维护一个功能丰富、视觉精美的博客,而不需要自己搭建后端。为此项目提供了:
- 配置驱动的站点定制:站点名、主题色、时区、语言、特色页面开关全部集中在
src/config/siteConfig.ts,与页面模板分离。 - 内容与代码分离(可选):通过
ENABLE_CONTENT_SYNC环境变量,可以把文章、数据、图片放进独立的内容仓库,构建前由scripts/sync-content.js同步进来。 - 丰富的第一方特色页面:追番(本地/Bangumi/Bilibili 三种数据源)、友链、日记、相册、项目、技能、设备、时间线、AI 工具页。
- 静态友好的动态能力:搜索(Pagefind)、评论(Twikoo/Giscus 外挂)、音乐播放器(本地/Meting)、Live2D 看板娘。
运行环境要求(来自 README 徽章与 packageManager 字段):
| 项目 | 要求 |
|---|---|
| Node.js | >= 20 |
| pnpm | >= 11(package.json 声明 pnpm@11.5.3,并通过 preinstall 钩子 npx only-allow pnpm 强制使用) |
| Astro | 7.1.3 |
| TypeScript | 6.0.3 |
| 许可证 | Apache-2.0(README 徽章;仓库同时包含 LICENSE.MIT 与 THIRD_PARTY_NOTICES.md) |
架构(Architecture)
Mizuki 采用"构建期静态生成 + 少量客户端水合"的架构。Astro 页面默认输出零 JS 的 HTML;需要交互的部分(主题切换、音乐播放器、搜索、Live2D、Swup 过渡等)通过 Svelte 岛屿按需水合。
各层职责说明:
- 构建脚本层:
package.json中的 scripts 是整个仓库的"操作系统"。predev/prebuild钩子在每次 dev/build 前自动执行内容同步(|| true保证同步失败不阻断本地开发);build命令串联了追番数据更新、Astro 构建、全局样式加载检查、Pagefind 索引、字体加载检查五个步骤。 - 配置层:配置被拆分为多个单一职责模块(README 明确要求"不要为了修改页面内容而直接编辑
src/pages/*.astro"),src/config/index.ts作为统一导出入口。这是典型的 convention over configuration + 配置/模板分离 设计,让升级模板代码时用户的定制改动不会冲突。 - 内容与数据层:纯声明式数据。文章是 frontmatter 驱动的 Markdown/MDX;结构化页面数据是带类型的
src/data/*.ts;相册是文件系统目录 +info.json。 - 渲染层:Astro 页面负责布局与路由,Svelte 组件(
@astrojs/svelte9.0.1)负责水合的交互岛屿,Tailwind CSS 4 + PostCSS + Stylus 提供样式。 - 产物层:纯静态 HTML + Pagefind 索引 + 全文 RSS/Atom(复用文章页的 Markdown/MDX 管线)。
命令与构建管线
以下脚本定义在项目根 package.json,是所有开发流程的唯一入口:
| 命令 | 作用 |
|---|---|
pnpm install | 安装依赖(preinstall 执行 npx only-allow pnpm,强制使用 pnpm) |
pnpm dev / pnpm start | 启动开发服务器(http://localhost:3000);predev 先同步外部内容仓库 |
pnpm build | 完整生产构建(详见下方分解) |
pnpm preview | 预览生产构建 |
pnpm run check | Astro 诊断(astro check) |
pnpm run type-check | TypeScript 类型检查(tsc --noEmit) |
pnpm test | 运行 Markdown、布局、图片、音乐加载及加密测试 |
pnpm run format / pnpm run lint | Biome 格式化 / 检查修复 |
pnpm new-post -- <文件名> | 创建 .md 或 .mdx 文章 |
pnpm run sync-content | 同步外部内容仓库 |
pnpm run init-content | 交互式初始化外部内容同步 |
pnpm run update-anime / update-bangumi / update-bilibili | 抓取追番数据 |
pnpm run prepare-fonts / check-fonts / prepare-images | 字体与默认图片准备 |
pnpm run export-config | 导出配置(scripts/export-config.mjs) |
pnpm run submit | IndexNow 提交(scripts/indexnow-submit.js) |
build 是最值得关注的复合命令,原文为:
"build": "node scripts/update-anime.mjs && astro build && node scripts/check-global-style-loading.mjs && pagefind --site dist && node scripts/check-font-loading.mjs"Source: package.json
其设计意图是把"容易在线上才暴露的回归"前置到构建期:构建完成后立即校验全局样式是否被正确加载、字体是否可用,失败即让 CI 报错,而不是等用户打开页面发现样式塌了。Pagefind 索引放在样式检查之前、字体检查之前之后串联执行,保证索引基于完整产物生成。
技术栈与核心依赖
完整依赖见 package.json。按用途归类:
| 类别 | 关键依赖 | 用途 |
|---|---|---|
| 框架 | astro 7.1.3、@astrojs/svelte、@astrojs/mdx、@astrojs/rss、@astrojs/sitemap | 静态生成、MDX、订阅与站点地图 |
| UI | svelte 5.56.7、tailwindcss 4、@tailwindcss/typography、stylus、@swup/astro | 交互岛屿、样式系统、页面过渡动画 |
| 代码高亮 | astro-expressive-code + 3 个 EC 插件、ec-lang-logo | 增强代码块(折叠段落、行号、语言 logo) |
| Markdown | remark-directive、remark-directive-rehype、remark-math + rehype-katex、rehype-slug、rehype-autolink-headings、rehype-code-group、rehype-components、remark-sectionize、github-slugger | 自定义语法扩展管线 |
| 搜索 | pagefind 1.5.2 | 静态搜索索引 |
| 交互组件 | @fancyapps/ui(Fancybox 灯箱)、@iconify/svelte + 多套 icon 图标集、astro-icon、overlayscrollbars、l2d-widget(Live2D 看板娘)、qrcode | 视觉与交互增强 |
| 内容处理 | gray-matter(frontmatter)、marked、sanitize-html、node-html-parser、reading-time、hastscript、unist-util-visit | 内容解析、HTML 清洗、阅读时长 |
| 数据/工具 | axios、dayjs、pako(加密文章用压缩)、takumi-js、oddmisc | 网络、日期、压缩 |
| 构建工具 | @biomejs/biome(lint/format)、@rollup/plugin-yaml、sharp、fonteditor-core、glob | 代码质量、资源处理 |
一个值得注意的细节:katex、pako、sanitize-html、axios 等库位于 dependencies 而非 devDependencies,因为部分处理(如浏览器端加密文章、追番数据抓取脚本)在运行/构建时都会用到。
内容模型与目录地图
Mizuki 把"页面模板"与"页面内容"严格分离(README 原文:不要为了修改页面内容而直接编辑 src/pages/*.astro;这些文件负责布局和渲染逻辑):
| 页面 | 内容/数据来源 | 说明 |
|---|---|---|
| 关于 | src/content/spec/about.md | Markdown 编写 |
| 友链 | src/content/spec/friends.md + src/data/friends.ts | 卡片与标签 |
| 追番 | src/config/siteConfig.ts 设数据源模式;本地数据在 src/data/anime.ts | 支持 Bangumi / Bilibili |
| 日记 | src/data/diary.ts 或 diaryApiUrl 配置 Memos 地址 | 文字、图片、位置、心情、标签 |
| 相册 | public/images/albums/,每个本地相册一个 info.json | 可选加密 |
| 项目 / 技能 / 设备 / 时间线 / AI 工具 | src/data/projects.ts / skills.ts / devices.ts / timeline.ts / ai-tools.ts | 结构化 TS 数据 |
| 文章 | `src/content/posts/*.md | .mdx` |
各特色页面通过 siteConfig.featurePages 开关批量启用/禁用(anime、diary、friends、projects、skills、timeline、albums、devices、aiTools 九个布尔位),这是"功能可选化"的顶层控制点——关闭后对应路由不再生成,减小站点体积。
图片放置约定(来自 README):
- 文章本地图片:放在文章旁边,用相对路径
./cover.webp引用(Astro 内容集合会跟随解析)。 - 公共图片:放在
public/下,用根路径/images/example.webp引用。
代码/内容分离机制
Mizuki 支持把主题代码和博客内容拆成两个仓库(可选功能),用于私有内容、独立版本管理或团队协作。README 给出的官方示例:
1# 本地内容模式(推荐入门使用)
2# 在 .env 中显式关闭同步
3ENABLE_CONTENT_SYNC=false
4pnpm dev
5
6# 外部内容仓库模式
7# 1. 复制配置示例
8cp .env.example .env
9
10# 2. 编辑 .env
11ENABLE_CONTENT_SYNC=true
12CONTENT_REPO_URL=https://github.com/your-username/Mizuki-Content.git
13# CONTENT_DIR=./content # 可选,默认值即为此路径
14
15# 3. 同步内容并启动站点
16pnpm run sync-content
17pnpm devSource: README.md
同步链路的实现位置在 scripts/sync-content.js 与 scripts/init-content-repo.js,并通过 package.json 的 predev / prebuild 钩子自动触发:
"predev": "node scripts/sync-content.js || true",
"prebuild": "node scripts/sync-content.js || true"Source: package.json
设计意图有二:其一,pre 钩子让开发者无需记忆"先同步再构建",流程不可绕过;其二,|| true 使同步脚本失败(例如断网、内容仓库为私有且未配凭证)时不阻断本地开发,只在真正需要最新内容的 CI 构建场景才应视为失败。外部内容仓库的结构约定为:
1Mizuki-Content/
2├── posts/ # .md 和 .mdx 文章
3├── spec/ # 关于页、友链页等 Markdown 内容
4├── data/ # 项目、技能等结构化页面数据
5└── images/ # 公共图片,包括相册和文章资源Source: README.md
配置体系
配置拆分到 src/config/ 下的多个模块,src/config/index.ts 是统一导出入口。主站点设置在 src/config/siteConfig.ts,README 给出的模板示例:
1export const siteConfig: SiteConfig = {
2 title: "您的博客名称",
3 subtitle: "您的博客描述",
4 siteURL: "https://example.com/", // 保留结尾斜杠
5 lang: "zh_CN", // 例如 "en"、"ja" 或 "zh_TW"
6 timeZone: "Asia/Shanghai", // 任意有效的 IANA 时区
7 themeColor: {
8 hue: 210, // 0–360
9 fixed: false, // 为 true 时隐藏访客的主题色选择器
10 },
11 featurePages: {
12 anime: true,
13 diary: true,
14 friends: true,
15 projects: true,
16 skills: true,
17 timeline: true,
18 albums: true,
19 devices: true,
20 aiTools: true,
21 },
22 // 其余字段请保留模板默认值。
23};Source: README.md
各配置模块职责一览:
| 模块 | 职责 |
|---|---|
siteConfig.ts | 站点标题、副标题、siteURL、lang、timeZone、主题色、featurePages 页面开关 |
navBarConfig.ts | 导航链接与菜单 |
profileConfig.ts | 头像、名称、简介、社交链接 |
sidebarConfig.ts | 侧边栏组件、顺序、位置、响应式行为 |
backgroundWallpaper.ts / effectsConfig.ts | 壁纸与视觉特效(透明度、模糊) |
commentConfig.ts | Twikoo 或 Giscus 评论(默认关闭,需 enable: true + 服务配置) |
musicConfig.ts | 音乐播放器模式与歌单来源(本地 / Meting) |
markdownConfig.ts | Wiki Link、自动图片网格、PlantUML 服务器地址 |
permalinkConfig.ts | 可选的全局固定链接格式 |
expressiveCodeConfig.ts | 代码块主题与行为 |
关键运行要求:部署前必须将 siteURL 替换为真实公开网址(RSS、sitemap、Open Graph 均依赖它);siteURL 必须保留结尾斜杠。环境变量参照 .env.example 配置,其中包含 Bilibili 会话数据与 IndexNow 凭据等可选项,不应提交真实值到 Git,托管平台应使用 Secret 机制。
核心流程
一次典型生产构建的端到端时序:
设计意图解读:
- 顺序讲究:追番数据更新放在
astro build之前,确保页面渲染时拿到的是最新数据;而全局样式/字体检查放在构建之后,因为它们校验的是最终产物的行为(HTML 里样式表是否真的被引用、字体是否可达),这是对"链接错误 / 路径回退失败"这类静态站点最常见回归的防线。 - Pagefind 索引必须最后:索引必须基于完整的
dist/生成,所以放在样式检查之后、字体检查之前都可以,但绝不能在astro build结束前运行。 - 同步钩子的容错哲学:
|| true只保护本地开发体验;CI 中若需要强一致内容,应显式运行pnpm run sync-content并让失败传播。
失败模式与边界情况
依据 README 与脚本结构可确认的行为:
- 内容同步失败:
predev/prebuild钩子中的|| true使同步失败不阻断流程,站点会用本地已有(或模板自带的示例)内容继续构建。后果是:若模板示例内容未清理,线上可能出现示例文章。README 专门提醒"发布前请删除或替换示例内容"。 - 加密文章的安全边界:README 明确强调——加密文章不会进入 RSS 和 Atom,但浏览器端加密不是服务端访问控制。加密 HTML 仍会被完整下发到客户端,仅由 JS 在浏览器端解密(依赖
pako压缩 +sanitize-html清洗),任何能拿到静态文件的人理论上都能离线破解。这是静态站点的固有约束,不应存放真正敏感内容。 - PlantUML 公共服务器:PlantUML 图表默认发送到
src/config/markdownConfig.ts配置的公共服务器渲染,因此不要在图表中写入密码、Token 或隐私数据——这是显式声明的数据外发边界。 - 评论系统默认关闭:
commentConfig.ts中评论默认enable: false,需手动开启并配置 Twikoo/Giscus,避免模板开箱即用指向无效后端。 siteURL未替换:会导致 RSS/Atom/sitemap/Open Graph 中的绝对链接指向example.com,属于最常见的部署事故,README 在"快速开始"和"部署"两节都重复强调。- 构建自检失败:
check-global-style-loading.mjs/check-font-loading.mjs检测到回归时令pnpm build以非零退出码结束,CI 因此中断,防止坏产物上线。
性能与运维要点
- 静态优先:所有页面默认零 JS 输出,交互(主题切换、音乐、搜索、看板娘)通过 Svelte 岛屿按需水合,天然利于 LCP/TBT。
- 懒加载与缓存:README 在"性能优化"中声明了懒加载和缓存机制;图片增强包含响应式尺寸(
sharp负责构建期处理)。 - Swup 过渡:
@swup/astro提供无刷新页面切换动画,同时避免整页重载造成的资源重复请求。 - SEO:sitemap、robots.txt、RSS、Atom、可选 Open Graph 图片齐全;另有
pnpm run submit(IndexNow)可在发布后主动推送 URL 给搜索引擎。 - 代码质量门禁:Biome(
format/lint)+astro check+tsc --noEmit三层检查;pnpm test覆盖 Markdown 增强、布局回归、图片加载、音乐播放器加载与加密(tests/crypto.test.mjs等)。
扩展点
- 新增特色页面:在
src/data/添加结构化数据文件 → 在siteConfig.featurePages增加开关 → 新建src/pages/*.astro渲染模板。遵循现有"数据/模板/开关"三件套模式即可与模板体系对齐。 - 新增 Markdown 语法能力:管线已集中在 remark/rehype 插件链(
remark-directive、rehype-components、rehype-code-group等),新增能力即新增插件;markdownConfig.ts提供了无需改代码的调参入口。 - 自定义代码块:
expressiveCodeConfig.ts+ 已装的三枚 Expressive Code 插件(collapsible-sections、line-numbers)与ec-lang-logo组合即可调整代码块外观。 - 迁移方向:官方指向重构版 Shirone,功能基本一致但架构重写,长期维护应评估迁移。
相关链接
- README.md — 中文主文档(快速开始、配置指南、内容分离)
- package.json — 命令与依赖清单
- astro.config.mjs — Astro 集成配置
- svelte.config.js / tsconfig.json — Svelte 与 TypeScript 配置
- src/content.config.ts — 内容集合定义
- 用户文档站 / 在线演示
- 兄弟页面:各配置模块详解、Markdown 扩展语法、特色页面实现、浏览器端加密——见 Wiki 对应目录