nodejs: 能在线编辑 Markdown 文档的 Web 服务程序
开发一个基于 Node.js 和 mermaid.js 的 Web 服务器程序,实现在线编辑 Markdown 文档并支持 Mermaid 流程图渲染的功能。
·
开发一个基于 Node.js 和 mermaid.js 的 Web 服务器程序,实现在线编辑 Markdown 文档并支持 mermaid.js 流程图渲染的功能。我会为你搭建一个完整、可直接运行的服务端程序,包含核心的 Web 服务、Markdown 解析和 Mermaid 渲染能力。
实现思路
- 使用
Express作为基础 Web 框架搭建服务器 - 使用
marked解析 Markdown 内容,并配置 Mermaid 扩展 - 使用
mermaid实现流程图的渲染 - 提供一个简洁的前端编辑界面,支持实时预览
- 实现基本的文件保存/加载功能(本地文件存储)
完整实现代码
1. 项目初始化与依赖安装
首先创建项目并安装所需依赖:
创建项目目录
mkdir md-edit-app
cd md-edit-app
初始化 npm 项目
npm init -y
安装核心依赖
npm install express@4 marked@12
npm install cors body-parser fs-extra ejs
我用的 node.js 版本: 18.20 , 搭配的版本是
npm install express@4.18.3 marked@12.0.2
npm install cors@2.8.5 body-parser@1.20.2 fs-extra@11.2.0 ejs@3.1.9
2. 服务器主程序 (app.js)
const express = require('express');
const marked = require('marked');
// 移除 const mermaid = require('mermaid');
const cors = require('cors');
const bodyParser = require('body-parser');
const fs = require('fs-extra');
const path = require('path');
// 初始化 Express 应用
const app = express();
// 移除 mermaid 初始化代码 ↓
// mermaid.initialize({
// startOnLoad: false,
// theme: 'default',
// securityLevel: 'loose' // 允许更多的渲染选项
// });
// 配置 Marked 解析器,添加 Mermaid 支持
const renderer = new marked.Renderer();
// 重写代码块渲染逻辑,识别 mermaid 代码块
renderer.code = (code, language) => {
if (language === 'mermaid') {
// 为 Mermaid 代码块生成容器(仅保留代码,渲染交给前端)
return `<div class="mermaid">${code}</div>`;
}
// 其他代码块使用默认渲染
return `<pre><code class="language-${language}">${code}</code></pre>`;
};
// 配置 marked
marked.setOptions({
renderer: renderer,
highlight: true,
breaks: true,
gfm: true // 启用 GitHub 风格的 Markdown
});
// 中间件配置
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
// 设置模板引擎
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// 确保保存文件的目录存在
const DOCS_DIR = path.join(__dirname, 'docs');
fs.ensureDirSync(DOCS_DIR);
// 路由配置
// 首页 - 编辑器界面
app.get('/', (req, res) => {
res.render('editor', { title: 'Markdown 在线编辑器 (支持Mermaid)' });
});
// 解析 Markdown 为 HTML (API)
app.post('/api/parse', (req, res) => {
try {
const { markdown } = req.body;
if (!markdown) {
return res.status(400).json({ error: 'Markdown 内容不能为空' });
}
// 解析 Markdown 为 HTML
const html = marked.parse(markdown);
res.json({ html });
} catch (error) {
res.status(500).json({ error: '解析 Markdown 失败: ' + error.message });
}
});
// 保存文档 (API)
app.post('/api/save', (req, res) => {
try {
const { filename, content } = req.body;
if (!filename || !content) {
return res.status(400).json({ error: '文件名和内容不能为空' });
}
// 拼接文件路径
const filePath = path.join(DOCS_DIR, `${filename}.md`);
// 写入文件
fs.writeFileSync(filePath, content, 'utf8');
res.json({ success: true, message: '文件保存成功', filePath });
} catch (error) {
res.status(500).json({ error: '保存文件失败: ' + error.message });
}
});
// 加载文档 (API)
app.get('/api/load/:filename', (req, res) => {
try {
const { filename } = req.params;
const filePath = path.join(DOCS_DIR, `${filename}.md`);
// 检查文件是否存在
if (!fs.existsSync(filePath)) {
return res.status(404).json({ error: '文件不存在' });
}
// 读取文件内容
const content = fs.readFileSync(filePath, 'utf8');
res.json({ success: true, content });
} catch (error) {
res.status(500).json({ error: '加载文件失败: ' + error.message });
}
});
// 获取文档列表 (API)
app.get('/api/docs', (req, res) => {
try {
// 读取目录下所有 .md 文件
const files = fs.readdirSync(DOCS_DIR)
.filter(file => path.extname(file) === '.md')
.map(file => ({
name: path.basename(file, '.md'),
path: file
}));
res.json({ success: true, docs: files });
} catch (error) {
res.status(500).json({ error: '获取文档列表失败: ' + error.message });
}
});
// 启动服务器
const PORT = 8000;
app.listen(PORT, () => {
console.log(`服务器运行在: http://localhost:${PORT}`);
console.log(`文档保存目录: ${DOCS_DIR}`);
});
3. 前端编辑器页面 (views/editor.ejs)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %></title>
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
display: flex;
flex-direction: column;
height: 100vh;
}
.header {
background: #2c3e50;
color: white;
padding: 1rem;
text-align: center;
}
.container {
display: flex;
flex: 1;
overflow: hidden;
}
.editor-container, .preview-container {
flex: 1;
padding: 1rem;
overflow: hidden;
border: 1px solid #ddd;
}
textarea {
width: 100%;
height: 100%;
padding: 1rem;
font-family: 'Consolas', 'Monaco', monospace;
font-size: 14px;
border: none;
outline: none;
resize: none;
}
.preview {
width: 100%;
height: 100%;
overflow-y: auto;
padding: 1rem;
background: #f9f9f9;
}
.controls {
padding: 1rem;
background: #f1f1f1;
display: flex;
gap: 1rem;
}
button {
padding: 0.5rem 1rem;
background: #3498db;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background: #2980b9;
}
.file-input {
padding: 0.5rem;
}
pre {
background: #f4f4f4;
padding: 1rem;
border-radius: 4px;
overflow-x: auto;
}
code {
font-family: 'Consolas', 'Monaco', monospace;
}
</style>
</head>
<body>
<div class="header">
<h1>Markdown 在线编辑器 (支持 Mermaid 流程图)</h1>
</div>
<div class="controls">
<input type="text" id="filename" placeholder="输入文件名(无需.md)" value="demo">
<button id="saveBtn">保存文档</button>
<button id="loadBtn">加载文档</button>
<button id="refreshBtn">刷新预览</button>
</div>
<div class="container">
<div class="editor-container">
<textarea id="editor" placeholder="请输入 Markdown 内容...">
## Markdown 编辑器 (支持 Mermaid)
### 功能说明
- 支持标准 Markdown 语法
- 支持 Mermaid 流程图渲染
- 支持文档保存/加载
### Mermaid 示例
```mermaid
graph TD
A[开始] --> B{选择操作}
B -->|编辑| C[Markdown 编辑]
B -->|预览| D[实时预览]
C --> E[保存文档]
D --> E
E --> F[结束]
普通代码示例
console.log('Hello, Markdown!');
</textarea>
</div>
<div class="preview-container">
<div id="preview" class="preview"></div>
</div>
```
运行与使用说明
- 创建目录结构:
md-edit-app/
├── app.js // 服务器主程序
├── views/ // 模板目录
│ └── editor.ejs // 编辑器页面
├── public/ // 静态资源目录 (空即可)
└── docs/ // 文档保存目录 (自动创建)
- 启动服务器:
node app.js
-
访问编辑器:
打开浏览器访问http://localhost:8000即可看到 Markdown 编辑器界面 -
功能使用:
- 在左侧编辑框输入 Markdown 内容(包含 Mermaid 代码块)
- 点击「刷新预览」查看右侧渲染效果
- 输入文件名后,点击「保存文档」可将内容保存到服务器
- 输入已保存的文件名,点击「加载文档」可加载保存的内容
总结
- 核心功能:该程序基于 Express 搭建 Web 服务器,使用 marked 解析 Markdown,集成 mermaid.js 实现流程图渲染,提供了完整的在线编辑、预览、保存、加载功能。
- 技术栈:Node.js + Express + marked (Markdown解析) + mermaid.js (流程图渲染) + EJS (模板引擎)。
- 扩展建议:可进一步添加用户认证、多人协作、云存储、更多 Markdown 扩展(如表格、公式)等功能,也可优化前端界面使其更美观易用。
这个程序开箱即用,你可以直接复制代码运行,体验完整的 Markdown 在线编辑和 Mermaid 渲染功能。
更多推荐


所有评论(0)