跳转到主要内容
GNIX GAZETTE

万象拾遗录

深海般的生活,是我心底的华北浪革
POST

万象拾遗录架构与全链路部署实战:从源码到多平台上线

2026-09-19 14:30:00

万象拾遗录架构与全链路部署实战:从源码到多平台上线

2026-09-19 14:30:00/ 预计阅读 5 分钟 --技术

前言:为什么要重构这个博客?

在数字信息日益碎片化、算法推荐泛滥的今天,独立博客不仅是一个发表文字的窗口,更是一处承载思想深度与审美意志的数字自留地。

此前,我曾尝试过动态 CMS(如 Halo)以及基于其他生态的静态主题。但在长期的翻译与长文排版实践中,我愈发感受到传统模板的局限性:

  1. 排版质感缺失:普通 Markdown 渲染出的文章千篇一律,缺乏如报刊专栏、金石印信、边注旁批等富有人文温度与出版物仪式感的视觉表现;
  2. 框架笨重与黑盒:过度依赖复杂的动态服务端,或被绑定在特定平台的插件体系内,可定制性和掌控度大打折扣;
  3. 性能与维护成本:动态博客需要时刻提防数据库负载与安全隐患,而纯粹的静态化(SSG)才是个人写作、长期归档与极速访问的终极答案。

基于「脚踏实地出真货」的信条,我全面重构了如今的「万象拾遗录 (GNIX GAZETTE)」——采用现代化的 Astro 7 + Tailwind CSS v4 架构,融合 React、Svelte 与 MDX 的长处,构建了一整套兼具严谨报章美学与极客工程质量的现代数字出版博客。

本文将完整公开这套博客的技术全景、本地调试、核心配置、构建工序与多平台部署方案。


一、架构全景:现代 Web 与报章排印的交汇

本博客的设计哲学是「阅读优先、静态至上、混合驱动」。在底层架构上,我们拒绝盲目堆砌依赖,而是让每个工具各司其职:

  • 核心框架Astro 7(采用静态站点生成 output: 'static',真正实现零客户端 JS 运行时负担)
  • 构建工具与样式:Vite 6 + Tailwind CSS v4(通过 @tailwindcss/vite 直连,告别冗余的配置文件,基于 CSS 变量深度定制墨色、宣纸底与朱砂红令牌)
  • 多框架混编
    • React:负责评论系统(Waline)、Fancybox 高清画廊以及高复杂度交互模态框
    • Svelte:负责轻量微组件(如文章时间线折叠器、字数统计微件、动态文章分享按钮、智能链接预加载 PrefetchLinks)
    • MDX:支持在 Markdown 文档中无缝混入定制的排版组件
  • 中西文标点混排优化:集成 remark-cjk-friendly 与删除线修复插件,终结中英文混排时的空隙与折行异常
  • 松散加粗自动修复:自研 remark-fix-loose-bold.mjs,彻底解决原生 CommonMark 对中文标点后跟 ** 加粗语法解析失效的顽疾
  • 数学公式排版:集成 remark-math + rehype-katex,毫秒级服务端渲染高质量 LaTeX 公式
  • 代码高亮:依托 Shiki 双主题机制,自动适配浅色纸底(github-light)与深色夜墨(github-dark),支持代码块一键复制、智能换行与长代码平滑折叠
  • 27+ 款新报刊排印专属组件
    • 金石与徽记<Seal> 印章、<Badge> 专栏标牌、<Kbd> 键帽样式
    • 文卷与摘录<Note> 告白提示框、<PullQuote> 大字引语、<Sidenote> 侧边考据注记
    • 工序与流转<Steps> 步进指南、<Tabs> 多栏标签页、<Timeline> 历史年表
    • 多媒体与机密<LinkCard> 报刊微缩卡片、<Spoiler> 朱墨遮罩、<Plate> 典籍卷宗

二、本地开发与环境就绪

在开始部署之前,推荐先在本地机器完成环境准备与调试运行。

准备 Node.js 与 pnpm 运行环境

确保本地 Node.js 版本满足 >= 20.0.0(推荐 Node 22 LTS),并启用现代包管理器 pnpm

# 检查 node 版本
node -v

# 若未安装 pnpm,全局启用 corepack 或通过 npm 安装
corepack enable
# 或: npm install -g pnpm

获取源码并安装项目依赖

克隆博客代码仓库至本地工作区,并执行依赖安装:

# 进入项目目录
cd 开源博客

# 安装全部依赖(采用 pnpm 快速链接)
pnpm install

启动本地热重载开发服务

运行开发命令,即可在本地秒级启动 Astro 服务:

pnpm dev

终端将输出服务地址,默认监听在 http://localhost:3000。在浏览器打开即可预览博客,编辑任意文章(.mdx)或页面即可享受即时热更新(HMR)。


三、核心配置指引:量身定制你的报章

博客的所有全局变量与文案均进行了集中抽象,日常定制只需要修改几个关键配置文件:

1. 站点核心基础配置 (src/config/site.ts)

这是全站最重要的中枢,包含:

  • siteConfig:站点主标题(万象拾遗录)、报刊英文刊名(GNIX GAZETTE)、副标题、作者姓名(倪谅)、公开社交主页链接与头像 CDN 地址;
  • seoConfig:默认标题模板( - 万象拾遗录)、默认 OG 分享封面图、全站核心关键词;
  • i18nConfig:统一管理归档、说说、友链、隐私政策等全部界面的文字与描述,杜绝零散硬编码;
  • aboutConfig:配置关于页(/about)的生平履历、关注领域(focusAreas)、主力装备工具链(dailyGear)与「正在进行时(/now)」卡片。

2. 外部服务接入

  • 评论系统:支持 Waline。在 siteConfig.waline.serverURL 填入你的自建 Waline 接口地址;若暂不启用,留空即自动隐藏评论区;
  • 访问统计:原生内置 Umami 隐私友好型无 Cookie 分析。在 siteConfig.analytics.umami 数组中填入自建实例的 src 与站点 id 即可无感加载;
  • 搜索引擎主动推送:支持微软必应与百度的 IndexNow 协议。只需在构建环境变量中配置 INDEXNOW_KEY,构建时将自动生成验签文件。

四、构建流水线深度解析

我们在 package.json 中配置了兼顾效率与严谨的流水线构建脚本:

"scripts": {
  "build": "node scripts/indexnow-key.js && node scripts/build-commit-index.mjs && astro build"
}

当你执行 pnpm build 时,系统将按顺序执行三项核心工序:

[pnpm build]

     ├── 1. node scripts/indexnow-key.js
     │      └─ 自动注入 IndexNow 密钥验签文件至 public 目录

     ├── 2. node scripts/build-commit-index.mjs
     │      ├─ 扫描本地 Git 完整提交记录 (Commit Logs)
     │      ├─ 统计全站代码、文章与动态的变更行数与时间轴
     │      └─ 增量写入 src/data/commit-index.json (驱动全站建站统计与文章更新追溯)

     └── 3. astro build
            ├─ 静态解析全部 Content Collections
            ├─ 编译 MDX 报刊排版组件与双主题样式
            └─ 纯静态输出至 dist/ 目录 (Ready for Edge/CDN/Nginx)

五、生产环境部署方案

由于本博客编译后是标准的静态 HTML / CSS / JS 文件(位于 dist/),因此具有极强的环境亲和力。无论你偏好全托管边缘网络,还是手握云服务器,均可轻松搞定。

方案 A:Vercel 全托管部署(极简、自动化)

Vercel 是最省心的现代化前端托管平台,提供全球 Anycast CDN 与自动 SSL。

关联代码仓库

登录 Vercel,点击 Add New Project,导入你的 GitHub / GitLab 仓库。

配置构建命令与环境变量

  • Framework Preset:选择 Astro
  • Build Commandpnpm build
  • Output Directorydist
  • Install Commandpnpm install

绑定域名并生效

点击 Deploy,片刻即可上线。项目根目录下已预置专用的 vercel.json

  • 针对 /_astro/* 静态指纹资源自动配置长达 1 年的 Cache-Control: immutable 极致强缓存;
  • 预设 X-Frame-OptionsX-Content-Type-Options 等完备的安全响应头;
  • 针对 *.xml(RSS 与 Sitemap)配置跨域友好支持。

方案 B:Cloudflare Workers / Pages 边缘部署

Cloudflare 的网络覆盖极广且防护能力强悍,博客内已预设 Cloudflare Worker 适配文件。

项目根目录下已包含定制的 wrangler.tomlsrc/worker.js

name = "gnix807-blog"
compatibility_date = "2025-04-01"
main = "src/worker.js"

[assets]
directory = "./dist"
binding = "ASSETS"

在本地或 CI 中只需一行命令即可将 dist 资产直推至 Cloudflare 边缘:

# 登录 Cloudflare(首次)
pnpm exec wrangler login

# 生产环境打包并直推
pnpm build
pnpm exec wrangler deploy

src/worker.js 内部包含了边缘级 404 自适应转发逻辑,确保无服务化路由运行顺畅。

如果你习惯使用 Cloudflare Pages 的 Git 集成:

  1. 在 Cloudflare 控制台新建 Pages 项目,连接 Git 仓库;
  2. 构建预设选择 Astro,构建命令填入 pnpm build,输出目录填入 dist
  3. 环境变量添加 NODE_VERSION = 22
  4. 点击保存并部署,即可享受无限免费请求额度与全站 HTTPS。

方案 C:自建 VPS / Nginx / 1Panel 部署(完全自主把控)

如果你拥有一台云服务器(如 Debian 12 / Ubuntu),并使用 1Panel 或原生 Nginx 管理:

服务器环境初始化

确保服务器已安装 Nginx,并在 1Panel 或宝塔中新建一个静态网站,将网站根目录指向部署包解压后的路径(例如 /opt/1panel/apps/openresty/www/sites/blog/index)。

配置 Nginx 伪静态与核心规则

在 Nginx 站点配置的 server 块中加入关键伪静态匹配,防止页面刷新或直接输入 URL 时 404:

server {
    listen 80;
    listen 443 ssl http2;
    server_name blog.gnix807.top;

    root /www/sites/blog/dist;
    index index.html;

    # 核心:SPA/静态生成页面伪静态解析
    location / {
        try_files $uri $uri/ $uri.html /404.html;
    }

    # 静态资源强缓存 (带 hash 的 js/css/图片)
    location ~* \.(?:css|js|woff2?|png|jpg|jpeg|gif|ico|svg|webp)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # 开启 gzip 压缩加速文字传输
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
}

自动化一键发布脚本 (deploy.sh)

在服务器项目根目录编写自动化拉取构建脚本:

#!/usr/bin/env bash
set -e

echo "=== 开始拉取最新代码 ==="
git pull origin main

echo "=== 依赖检查与静态编译 ==="
pnpm install --frozen-lockfile
pnpm build

echo "=== 同步产物至 Web 目录 ==="
rsync -av --delete dist/ /www/sites/blog/dist/

echo "=== 发布完成,站点已更新! ==="

六、踩坑经验与排坑手册

在从零搭建、设计与调优这套现代出版物博客的过程中,我记录下了几个极其隐蔽但至关重要的技术痛点:

1. Markdown 中文混排加粗失效 (** loose bold 陷阱)

  • 现象:在标准 Markdown 中,如果 ** 前后紧邻中文标点符号(如 ,**关键点**。),CommonMark 解析器由于西文分词规则限制,常常拒绝将其识别为粗体,而是原样输出星号。
  • 对策:我们在项目中自研并挂载了 remark-fix-loose-bold.mjs AST 插件,在语法树预处理阶段自动消除此兼容性缺陷,让日常写作再无语法后顾之忧。

2. 全本地字体切片加载与隐私

  • 经验:本博客放弃了外部公共字体 CDN(易受网络波动、域名被污染或隐私合规问题影响),转而将 Inter VariableNoto Serif SC(思源宋体)、Noto Sans SC(思源黑体)与 JetBrains Mono 完整的 WOFF2 切片全量存放在 /public/fonts/ 下本地直出。配合 font-display: swap 与精确的 unicode-range,首屏文字展现干净利落,彻底杜绝字体闪烁。

3. CI 构建时的 Commit 历史截断

  • 经验:许多 CI 平台默认采用 git clone --depth=1 浅克隆。如果直接运行依赖历史提交记录的工具,会导致统计页面只剩一条 Commit。为此,scripts/build-commit-index.mjs 会优先探测当前 Git 树的深度;若历史不足,会触发增量补丁模式或通过 GitHub API 获取远端历史作为安全兜底。

结语:脚踏实地出真货

将一个原本朴素的开源框架,打磨成今天你所见到的这套兼具排版温度与现代化工程链路的「万象拾遗录」,耗费了数个日夜的反复雕琢。

博客从不该只是冷冰冰的代码托管仓库,它是写作者思想与审美的一面镜子。从每一次排版组件的对齐,到每一行 CI 部署脚本的验证,脚踏实地,方出真货。

深海般的生活,是我心底的华北浪革。 记录翻译实践、历史考据、现代 Web 排版与生活思考。脚踏实地出真货。

——《万象拾遗录》刊首语
C

万象拾遗录架构与全链路部署实战:从源码到多平台上线

作者
倪谅
发布于
2026-09-19 14:30:00
许可协议

Comments

分类筛选: