2025 年开源项目与实战分享:Vue 3 Markdown 渲染组件 Vue Markdown Design

24 阅读6分钟

项目地址github.com/ZeroOneJs/m…
国内地址gitee.com/ZeroOneJs/m…
在线文档markdown-design.pages.dev

一、🚀 项目背景

1.1 痛点

当时我正在做一个知识管理类项目,其中有这样一个需求:需要将 Markdown 文本解析并渲染成对应的 HTML 页面,同时还要支持全文搜索和目录生成。

由于项目使用的是 Vue 3 框架,于是我在 awesome-vue 上搜了一圈,结果发现大部分项目仅提供基础的预览功能,而且 star 数最高的项目竟然还停留在 Vue 2 框架。面对这种窘境,我不得不自己动手写一个,于是 Vue Markdown Design 应运而生。

awesome-vue

🎉 彩蛋:在写这篇文章的时候,markdown-designVue Markdown Design 是其核心包之一)这个开源项目已经成功收录到 awesome-vue 的 Markdown 分类中。

markdown-design被awesome-vue收录

1.2 开源初心

作为一名开源新人,最初的想法很简单:通过这个项目学习一下前沿的前端工程化思想(其实是想找工作的时候有东西可以吹😎)。

然而,"一入开源深似海"——从架构设计到 CI/CD,从测试策略到文档建设,这一路踩坑无数,却也收获满满。今天正好通过这篇文章跟大家分享一下我的开源踩坑经历。

二、🏗️ 开源实战之 Monorepo 架构设计

2.1 为什么选择 Monorepo?

Monorepo 是现代开源项目的主流架构模式之一,它具有代码共享与复用、依赖管理简化和跨包协作便捷等优点。

本项目基于 markdown-it 构建,所以开发 markdown-it 插件是必不可少的环节。采用 Monorepo 架构,可以将 Vue 组件与 markdown-it 插件充分解耦,既保证了模块独立性,也为后续跨框架扩展打下基础。

2.2 项目结构一览

markdown-design/
├── packages/
│ ├── vue-markdown-design/ # Vue 3 组件库
│ ├── markdown-it-sanitize/ # markdown-it HTML 安全过滤插件
│ └── markdown-it-headers/ # markdown-it 标题提取插件

三、🧪 开源实战之自动化测试

3.1 技术选型

自动化测试是开源项目的质量防线,它可以保障功能稳定,降低维护风险,提高协作效率等。

由于当时 Vitest浏览器模式还不够稳定,经过权衡,我同时使用 VitestCypress 来覆盖不同的测试场景:

工具测试类型覆盖范围
CypressE2E 测试组件渲染、用户交互、视觉回归
Vitest单元测试工具函数、插件核心逻辑

然后再配合 GitHub Actions,在我每次推送代码到 GitHub 时自动跑一遍测试流程,这就完成了项目的自动化测试。

3.2 踩坑实录:中文文本的"水土不服"

问题描述

由于测试 Markdown 组件需要用到大量文本,我本想着作为一个中国人不能学老外用英文文本,所以用了中文文本作为测试。结果本地运行一切正常,但一到了 GitHub Actions 就出现了许多用例测试不通过的情况。

🔍 原因分析

通过在 Docker 中模拟 CI 环境复现失败用例,最后查看失败截图发现是因为 CI 环境缺少中文字体包,导致中文会被全部渲染为「□□□」乱码。

中文乱码

解决方案

  • 方案 A:将测试文本统一替换为英文

  • 方案 B:通过流水线脚本为 CI 环境安装中文字体包

四、📦 开源实战之自动化发布

4.1 技术选型

自动化发布我使用的是 Release Please,这是 Google 专为 GitHub 优化的开源自动化发布工具。其工作流程如下:

  1. 开发者推送代码到 main 分支
  2. Release Please 分析提交信息,自动生成 CHANGELOG
  3. 创建一个包含版本号和更新日志的 Release PR
  4. 开发者手动审核并合并 PR
  5. Release Please 自动发布到 npm 并创建 GitHub Release

4.2 踩坑实录:<details> 文本引发的发布事故

问题描述

在我合并 Release PR 后,npm 发布流水线会中断并报以下错误:

流水线报错

🔍 原因分析

通过本地 debug Release Please,发现在发布 npm 版本前,Release Please 会解析 PR 中的 <details> 标签以提取特定信息。如果 git 提交信息中恰好包含 <details> 文本(如示例),Release Please 会误将其识别为需要处理的元素,但单个标签无内容时会导致解析失败,这时流水线就会中断并报错。

fix(toc): improve toc generation for content within collapsible elements (e.g., <details>)

解决方案

PR 的更新日志中,将 <details> 改为 details,避免被误解析。

五、📚 开源实战之开发文档

5.1 技术选型

开发文档我采用的是 VitePress 构建,这是 Vue 团队出品的静态站点生成框架,只需要简单的配置就能实现全文搜索、国际化、响应式布局等丰富的功能。

5.2 部署方案

部署文档我使用的是 Cloudflare Pages,这是 Cloudflare 的静态站点托管服务,选择它是因为:

  • 全球 CDN 加速:在国内外都能获得不错的访问速度
  • 免费额度充足:个人项目完全够用
  • 与 GitHub 集成:推送即部署

5.3 踩坑实录:SPA 路由与重定向的博弈

问题描述

由于文档没有传统意义上的 /index,默认进入首页需要重定向到 /guide/introduction。好在 Cloudflare 提供了这个能力。只需要在项目的 public/_redirects 文件中配置:

/ /guide/introduction

项目部署到 Cloudflare Pages 后,直接访问 / 时重定向正常,但点击 Logo 位置访问 /404

404

🔍 原因分析

VitePress 是单页应用(SPA),点击 Logo 跳转 / 是前端路由行为,不会触发真实的 HTTP 请求,因此 Cloudflare 的服务端重定向规则不会生效。

解决方案

创建一个动态的 /index 页面,在前端处理重定向逻辑:

<script setup>
  import { useRouter } from "vitepress";
  router.go('/guide/introduction', { replace: true });
</script>

六、🧩 组件使用指南

6.1 核心组件矩阵

Vue Markdown Design组件

前面已经介绍过 Vue Markdown Designmarkdown-design 的主包,它的主要功能如下:

组件名功能定位
Render集成 Markdown 解析、渲染,提供其他 Markdown 常用功能
Search为渲染内容提供全文搜索功能
Toc为渲染内容提供目录生成功能
Markdown集成上述所有功能,并对组件布局做了专门优化

6.2 三种使用模式

方案特点适用场景
单用 Markdown开箱即用,功能完备,内置响应式布局快速接入、移动端适配、无特殊布局需求
Render + Search + Toc灵活组合,各组件职责单一,布局完全自主深度定制、与现有 UI 集成
Markdown + Search/Toc保留完整功能的同时,增强自定义布局能力搜索或目录等单一组件有额外布局需求

6.3 快速开始

📥 安装

npm i vue-markdown-design

🎯 使用

// main.js
// 引入组件
import VueMarkdown from 'vue-markdown-design'
import { createApp } from 'vue'

const app = createApp()

// 注册组件
app.use(VueMarkdown)
app.mount('#app')
<!-- App.vue -->
<vue-markdown :src="`# 标题\n内容`" />

更多使用方式请看:markdown-design.pages.dev

七、🗺️ 未来规划

这个项目还在继续维护,以下是我未来的开发计划:

方向优先级
🧪 测试工具全面迁移至 Vitest⭐⭐⭐⭐⭐
⬇️ 支持 Markdown Stream⭐⭐⭐⭐
📉 减少第三方依赖⭐⭐⭐
🌙 暗色模式⭐⭐⭐
🖥️ 支持 SSR 服务端⭐⭐
⚛️ React 版本⭐⭐

如果你有好的想法或建议,欢迎提交 Issues,我会择优进行优先开发👏

📝 结语

其实写这篇文章的目的非常简单,就是来给这个项目打个广告。如果它对你有所帮助,请给项目点个 ⭐Star,你的每一份支持都是我前进的动力!感谢🙏。