Repository Wiki
LyraVoid/Mizuki

项目概览

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 强制使用)
Astro7.1.3
TypeScript6.0.3
许可证Apache-2.0(README 徽章;仓库同时包含 LICENSE.MIT 与 THIRD_PARTY_NOTICES.md)

架构(Architecture)

Mizuki 采用"构建期静态生成 + 少量客户端水合"的架构。Astro 页面默认输出零 JS 的 HTML;需要交互的部分(主题切换、音乐播放器、搜索、Live2D、Swup 过渡等)通过 Svelte 岛屿按需水合。

Loading diagram...

各层职责说明:

  • 构建脚本层: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/svelte 9.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 checkAstro 诊断(astro check)
pnpm run type-checkTypeScript 类型检查(tsc --noEmit)
pnpm test运行 Markdown、布局、图片、音乐加载及加密测试
pnpm run format / pnpm run lintBiome 格式化 / 检查修复
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 submitIndexNow 提交(scripts/indexnow-submit.js)

build 是最值得关注的复合命令,原文为:

json
"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、订阅与站点地图
UIsvelte 5.56.7、tailwindcss 4、@tailwindcss/typography、stylus、@swup/astro交互岛屿、样式系统、页面过渡动画
代码高亮astro-expressive-code + 3 个 EC 插件、ec-lang-logo增强代码块(折叠段落、行号、语言 logo)
Markdownremark-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.mdMarkdown 编写
友链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 给出的官方示例:

bash
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 dev

Source: README.md

同步链路的实现位置在 scripts/sync-content.js 与 scripts/init-content-repo.js,并通过 package.json 的 predev / prebuild 钩子自动触发:

json
"predev": "node scripts/sync-content.js || true", "prebuild": "node scripts/sync-content.js || true"

Source: package.json

设计意图有二:其一,pre 钩子让开发者无需记忆"先同步再构建",流程不可绕过;其二,|| true 使同步脚本失败(例如断网、内容仓库为私有且未配凭证)时不阻断本地开发,只在真正需要最新内容的 CI 构建场景才应视为失败。外部内容仓库的结构约定为:

text
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 给出的模板示例:

typescript
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.tsTwikoo 或 Giscus 评论(默认关闭,需 enable: true + 服务配置)
musicConfig.ts音乐播放器模式与歌单来源(本地 / Meting)
markdownConfig.tsWiki Link、自动图片网格、PlantUML 服务器地址
permalinkConfig.ts可选的全局固定链接格式
expressiveCodeConfig.ts代码块主题与行为

关键运行要求:部署前必须将 siteURL 替换为真实公开网址(RSS、sitemap、Open Graph 均依赖它);siteURL 必须保留结尾斜杠。环境变量参照 .env.example 配置,其中包含 Bilibili 会话数据与 IndexNow 凭据等可选项,不应提交真实值到 Git,托管平台应使用 Secret 机制。

核心流程

一次典型生产构建的端到端时序:

Loading diagram...

设计意图解读:

  1. 顺序讲究:追番数据更新放在 astro build 之前,确保页面渲染时拿到的是最新数据;而全局样式/字体检查放在构建之后,因为它们校验的是最终产物的行为(HTML 里样式表是否真的被引用、字体是否可达),这是对"链接错误 / 路径回退失败"这类静态站点最常见回归的防线。
  2. Pagefind 索引必须最后:索引必须基于完整的 dist/ 生成,所以放在样式检查之后、字体检查之前都可以,但绝不能在 astro build 结束前运行。
  3. 同步钩子的容错哲学:|| 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,功能基本一致但架构重写,长期维护应评估迁移。

相关链接

Sources

(2 files)