← 返回个人网站搭建

Project Update

代码工程阅读器:在帖子中展示完整项目目录

2026-07-18 · 个人网站搭建 · Astro · Decap CMS · Monaco Editor · fflate · 代码展示

为什么需要代码工程阅读器

普通 Markdown 代码块很适合展示一小段示例,但不适合展示包含多个模块、配置文件和测试目录的完整工程。

如果把每个文件分别复制到文章中,会出现几个问题:

  • 文件之间的目录关系消失。
  • 文章会被大量代码拉得很长。
  • 更新项目时容易遗漏某些文件。
  • 读者很难像使用编辑器一样快速切换文件。

因此网站新增了一种可选的帖子展示能力:正文继续负责说明,正文下方使用左侧文件树和右侧代码区展示完整工程。

三类帖子共用同一套数据结构

Blog、Study 和 Projects 原本就共用基础内容 schema,因此代码工程配置也放进公共字段中:

codeProject:
  enabled: true
  archive: /src/code-project-archives/example.zip
  entry: src/main.py
  title: 示例代码工程

各字段的作用是:

  • enabled:控制当前帖子是否启用阅读器。
  • archive:CMS 上传的 ZIP 代码包路径。
  • entry:打开页面时默认显示的文件。
  • title:阅读器标题,不填写时使用帖子标题。

旧帖子没有 codeProject 字段时仍然使用原有阅读版式,不需要批量修改历史内容。

CMS 为什么上传 ZIP

Decap CMS 的文件控件适合上传单个文件,但不能稳定地把一个本地文件夹及其层级作为一个字段提交。

第一版采用 ZIP 作为交换格式:

  1. 在本地将代码文件夹压缩为 .zip
  2. 在 CMS 中展开“代码工程阅读器”。
  3. 开启代码工程展示并上传 ZIP。
  4. 填写默认打开文件。
  5. 发布帖子并触发 Cloudflare Pages 重新构建。

目前构建流程只接受 ZIP,不接受 7z、RAR 等其他格式。这样可以保持浏览器上传、Node.js 构建和 Cloudflare 部署环境的一致性。

构建阶段生成安全预览

prepare-code-projects.mjs 会在 Astro 构建前执行。它不会把压缩包直接作为网页目录公开,而是进行以下处理:

CMS 上传 ZIP
  -> 构建阶段检查并解压
  -> 过滤无关或危险文件
  -> 生成 manifest.json
  -> 将可预览源码保存为 .txt
  -> Astro 构建静态页面

清单记录文件的相对路径、大小、语言、是否可以预览以及对应的安全文本资源。浏览器根据清单生成文件树,点击文件后再按需读取内容。

即使项目中包含 HTML 或 JavaScript 文件,发布产物也使用 .txt 承载源码,避免用户直接打开静态资源时把它当成页面或脚本执行。

代码包安全限制

代码工程是公开内容,但仍然需要避免误传敏感文件和异常压缩包。构建脚本包含以下限制:

  • ZIP 最大 20 MB。
  • 单个文件最大 2 MB。
  • 最多发布 500 个文件。
  • 解压后的可发布内容最大 30 MB。
  • 拒绝绝对路径和 .. 路径穿越。
  • 拒绝 .env、私钥、证书和常见凭据文件。
  • 自动过滤 .gitnode_modulesdist、缓存和构建目录。
  • 二进制文件只显示在目录中,不读取为代码文本。

代码只用于只读展示,不会在网站中运行。

Monaco Editor 阅读体验

右侧代码区域使用 Monaco Editor,也就是 VS Code 编辑器核心能力的网页版本。当前阅读器提供:

  • 文件类型语法高亮。
  • 行号、滚动和小地图。
  • 明暗主题同步。
  • 复制当前文件。
  • 自动换行切换。
  • 只读与 DOM 只读保护。
  • 手机端文件目录抽屉。

Monaco 体积较大,因此采用动态加载。只有真正启用了代码工程的帖子才会加载编辑器,普通文章不会承担这部分资源开销。

自动化验证

项目新增了代码包测试脚本:

npm run test:code-projects

测试会生成临时代码包并验证:

  • Python 和 JavaScript 文件能够识别语言。
  • 图片等二进制文件不会作为文本预览。
  • node_modules 会被忽略。
  • 包含 .env 的压缩包会构建失败。

完整站点仍然通过以下命令验证:

npm run build

本站实践总结

这套方案没有把网站变成在线 IDE,而是把“完整项目结构”和“文章说明”结合起来。

Markdown 适合讲清楚背景、设计和使用方法,代码工程阅读器适合让读者自由查看实现细节。两者组合后,项目帖子可以同时承担技术记录、源码导览和成果展示三种作用。