Markdown 渲染管线设计:从 MDX 到 HTML 的完整链路
技术架构(更新于 2026年5月29日)
Markdown 渲染的挑战
工具库的博客和教程系统需要将 MDX/Markdown 文件渲染为安全的 HTML。看似简单,实际涉及:
- 语法扩展:GFM 表格、任务列表、删除线
- 安全消毒:防止 XSS(用户不可信内容)
- 代码高亮:语法着色的
<pre><code>块 - 标题锚点:自动生成 slug 用于目录跳转
- 内部链接:
/pdf/merge转为带 locale 前缀的链接
unified 生态管线
MDX/Markdown 原文
↓ remark-parse (Markdown → MDAST)
↓ remark-gfm (GFM 扩展)
↓ remark-rehype (MDAST → HAST)
↓ rehype-slug (标题添加 id)
↓ rehype-stringify (HAST → HTML)
HTML 输出
工具库在 src/lib/blog/render-mdx.ts 中实现了这条管线:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkGfm from 'remark-gfm';
import remarkRehype from 'remark-rehype';
import rehypeSlug from 'rehype-slug';
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse)
.use(remarkGfm)
.use(remarkRehype, { allowDangerousHtml: false })
.use(rehypeSlug)
.use(rehypeStringify);
Frontmatter 解析
每篇文章的元数据通过 gray-matter 从 MDX 头部提取:
---
title: "文章标题"
description: "SEO 描述"
author: "老张(工具库站长)"
---
正文内容...
import matter from 'gray-matter';
const { data: frontmatter, content } = matter(rawMdx);
// frontmatter.title → "文章标题"
// content → 正文 Markdown
Frontmatter 用于 SEO metadata、Open Graph 标签和 JSON-LD 结构化数据。
安全考虑
禁止原始 HTML 注入
.use(remarkRehype, { allowDangerousHtml: false })
设置为 false 时,Markdown 中的 <script> 标签会被转义为文本,而非执行。
链接安全
外部链接应添加 rel="noopener noreferrer" 和 target="_blank":
// rehype 插件:为外部链接添加安全属性
function rehypeExternalLinks() {
return (tree) => {
visit(tree, 'element', (node) => {
if (node.tagName === 'a' && isExternal(node.properties.href)) {
node.properties.target = '_blank';
node.properties.rel = 'noopener noreferrer';
}
});
};
}
多语言内容管理
工具库的内容文件组织:
src/content/blog/my-article/
├── meta.json ← 共享元数据(分类、标签、日期)
├── zh-CN.mdx ← 简体中文正文
├── zh-TW.mdx ← 繁体中文正文
├── en.mdx ← 英文正文
└── ja.mdx ← 日文正文
meta.json 存储语言无关的数据,*.mdx 存储各语言的正文和 frontmatter。构建时 generateStaticParams 枚举所有 slug × locale 组合预渲染。
性能优化
构建时渲染 vs 运行时渲染
工具库选择构建时渲染(SSG):
next build → 读取 MDX → unified 处理 → HTML 写入 out/
运行时 → 直接返回静态 HTML(零处理开销)
对比运行时渲染(每次请求都处理 Markdown),SSG 的 TTFB 从 ~200ms 降至 ~50ms。
增量内容更新
新增或修改文章后需要重新 next build。对于 18+ 篇文章 × 4 语言 = 72 个页面,完整构建约 3-5 分钟。
与 MDX 组件的关系
当前工具库使用纯 Markdown(非 React 组件 MDX),优点是:
- 渲染管线简单,无 React SSR 开销
- 内容文件可被任何 Markdown 编辑器编辑
- 翻译工作只需处理纯文本
未来如需在文章中嵌入交互组件(如 live demo),可升级到 @next/mdx + React 组件。
总结
Markdown 渲染管线是内容驱动网站的核心基础设施。remark/rehype 生态提供了可组合的处理器链,gray-matter 处理元数据,构建时渲染确保极致性能。工具库的博客系统正是这套架构的实战应用。
本站提供浏览器本地工具,免注册即可试用 →
#Markdown#MDX#remark#rehype#内容渲染