返回文章列表
· 约 歌鱼

本地博客编辑器

方便操作博客

我的博客使用 Astro 构建,所有文章都以 Markdown 文件保存在项目中。

这种方式很简单,也很可靠:文章就是文件,Git 负责版本管理,GitHub Pages 负责部署。但每次写作都要手动创建文件、填写 frontmatter、检查 slug,再打开浏览器确认排版。文章多起来之后,这些重复操作逐渐变成了写作过程中的阻力。

于是,我决定给博客做一个运行在本地 Docker 中的网页编辑器。

我想解决什么问题

这个编辑器并不是要替代 Markdown,而是希望在保留 Markdown 工作流的同时,让日常写作方便一些。

它需要支持:

  • 浏览和搜索已有文章
  • 新建、编辑和删除文章
  • 使用表单维护标题、日期、标签等 frontmatter
  • 实时预览 Markdown
  • 区分草稿和已发布文章
  • 提醒尚未保存的修改
  • 直接把文章保存到博客项目中

Markdown 文件仍然是内容的唯一真实来源。编辑器只负责降低操作成本,不接管博客的构建、版本控制和发布流程。

为什么做成独立项目

我的博客是一个部署在 GitHub Pages 上的纯静态 Astro 项目。

静态站点可以读取 Markdown 并生成页面,但它无法在浏览器中提供写文件接口。如果直接把编辑 API 加进 Astro,就需要把博客改成服务端运行模式,这会破坏现有的静态部署方式。

因此,我把编辑器做成了一个独立项目:

D:/ximu/
  blog/
  BlogEditor/

两个项目之间没有 npm workspace 或运行时依赖。编辑器拥有自己的源码、依赖、测试和 Docker 配置,只通过 Docker bind mount 访问博客的文章目录。

整体关系如下:

浏览器
  |
  v
BlogEditor 容器
  |
  v
../blog/src/content/posts
  |
  v
Astro 静态构建

这样一来,博客仍然可以按照原来的方式构建和部署,编辑器也可以独立演进。

编辑器的功能

编辑器启动后会直接进入写作工作台。

左侧是文章列表,可以按标题、slug 或标签搜索。右侧是文章编辑区域,其中 frontmatter 使用表单维护,正文继续使用 Markdown。

桌面端采用编辑与预览双栏布局,手机端则可以在编辑和预览之间切换。

目前支持的文章字段包括:

  • 标题
  • slug
  • 摘要
  • 发布日期
  • 更新日期
  • 标签
  • 封面图片路径
  • 草稿状态
  • Markdown 正文

编辑器还会记录文稿是否发生变化。切换文章、创建新文章或关闭页面时,如果存在未保存的内容,就会进行提醒。

保存操作支持页面按钮,也支持 Ctrl+SCmd+S

可靠地写入文件

保存文章时,我没有直接覆盖原文件。

服务端会先在文章目录中创建一个临时文件,完整写入新内容,然后通过 rename 替换原文件。

大致流程是:

写入临时文件
  |
  v
确认写入成功
  |
  v
rename 替换原文件

如果写入过程中发生异常,原文章仍然存在。相比直接修改原文件,这种方式可以降低进程中断或磁盘错误造成文章损坏的风险。

当然,这仍然是一个面向个人使用的本地工具,而不是可以直接部署到公网的内容管理系统。

保持 Astro 格式兼容

博客使用 Astro content collection 校验文章格式。

编辑器通过 gray-matter 解析和生成 frontmatter,并按照博客当前的字段结构保存文章:

---
title: 本地博客编辑器
description: 一个运行在本地 Docker 中的网页博客编辑器
pubDate: 2026-07-17
tags:
  - Docker
  - Astro
draft: true
---

保存后,Markdown 文件会直接出现在博客的文章目录中。

不过,编辑器自己的校验并不是最终标准。文章格式是否真正兼容,仍然需要由 Astro 构建确认。因此,在完成实现后,我重新执行了博客构建,确保现有文章和编辑器生成的格式都能被 content collection 正确读取。