在 Web 开发中,常需将 Markdown 文本(如接口文档、博客内容)渲染为美观的 HTML 页面。不同于纯文本展示,Markdown 渲染需要借助专门的库解析语法规则,再结合样式实现可视化。
一、前端渲染 Markdown 的核心逻辑
Markdown 本质是轻量级标记语言,无法直接被浏览器识别。前端渲染的核心流程如下:
- 解析:通过库将 Markdown 文本转换为 HTML 字符串;
- 渲染:将解析后的 HTML 插入页面 DOM 中;
- 美化:通过 CSS 优化排版(如标题间距、代码块高亮);
- 增强(可选):支持表格、公式、自定义组件等进阶功能。
目前主流的前端 Markdown 渲染库有 marked.js(轻量灵活)、showdown.js(功能全面)、React-Markdown(React 生态专用)等。
二、3 个主流渲染库实战教程
1. marked.js:轻量首选(原生 JS / 框架通用)
marked.js 是目前最流行的 Markdown 解析库之一,体积小、解析速度快,支持自定义渲染规则,适合原生 JS 项目或各类框架。
步骤 1:安装与引入
- CDN 引入(快速测试):
<!-- 引入 marked 核心库 -->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<!-- 可选:代码高亮需搭配 highlight.js -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/styles/github-dark.min.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/highlight.min.js"></script>
- npm 安装(工程化项目):
npm install marked highlight.js --save
步骤 2:基础渲染示例(原生 JS)
实现输入 Markdown 文本,实时预览渲染结果的功能:
// 1. 获取 DOM 元素
const input = document.getElementById('markdownInput');
const preview = document.getElementById('previewArea');
// 2. 配置 marked(启用代码高亮)
marked.setOptions({
highlight: (code, lang) => {
return lang && hljs.getLanguage(lang) ? hljs.highlight(code, { language: lang }).value : hljs.highlightAuto(code).value;
},
breaks: true,
gfm: true
});
// 3. 渲染函数
function renderMarkdown() {
const markdownText = input.value;
const html = marked.parse(markdownText);
preview.innerHTML = html;
}
// 4. 初始化渲染 + 监听输入变化
renderMarkdown();
input.addEventListener('input', renderMarkdown);
步骤 3:进阶配置(自定义渲染)
若需修改默认渲染规则,可通过 marked.Renderer() 实现:
const renderer = new marked.Renderer();
renderer.heading = (text, level) => {
return `<h${level}>${text}</h${level}>`;
};
renderer.link = (href, title, text) => {
const titleAttr = title ? `title="${title}"` : '';
return `<a href="${href}" ${titleAttr} target="_blank" rel="noopener">${text}</a>`;
};
const html = marked.parse(markdownText, { renderer });
2. React-Markdown:React 生态专用(安全无 XSS)
如果是 React 项目,推荐使用 react-markdown,它基于组件化思想,支持插件扩展,且默认过滤危险 HTML。
步骤 1:安装依赖
npm install react-markdown @types/react-markdown highlight.js --save
# 若需支持表格、公式等,需安装对应插件
npm install remark-gfm remark-math rehype-katex --save
步骤 2:React 组件示例
import React, { useState } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
import 'highlight.js/styles/github-light.min.css';
import 'katex/dist/katex.min.css';
const MarkdownPreview = () => {
const [markdownText, setMarkdownText] = useState(`# React-Markdown 示例
## 1. 表格
| 姓名 | 技术栈 |
|------|--------|
| 张三 | React |
## 2. 数学公式
欧拉公式:$e^{i\pi} + 1 = 0$`);
return (
<div style={{ display: 'flex', gap: '20px', padding: '20px' }}>
<textarea value={markdownText} onChange={(e) => setMarkdownText(e.target.value)} style={{ width: '40%', height: '600px', padding: '10px' }} />
<ReactMarkdown className="markdown-body"
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeKatex]}
style={{ width: '50%', padding: '20px', border: '1px solid #eee' }}
>
{markdownText}
</ReactMarkdown>
</div>
);
};
export default MarkdownPreview;
关键优势:
- 安全:默认不渲染 script、iframe 等危险标签;
- 插件化:通过 remark-* 和 rehype-* 插件支持复杂功能;
- TS 友好:自带类型定义。
3. showdown.js:功能全面(适合复杂场景)
showdown.js 支持更多自定义配置,适合企业级文档系统。
基础使用示例(Vue 项目):
<template>
<div>
<textarea v-model="markdownText" @input="render" placeholder="输入 Markdown..."></textarea>
<div v-html="htmlContent"></div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import showdown from 'showdown';
import hljs from 'highlight.js';
const converter = new showdown.Converter({
tables: true,
strikethrough: true,
autolink: true,
extensions: [
() => ({
type: 'output',
filter: (html) => {
return html.replace(/<pre><code([^>]*)>/g, '<pre><code$1>').replace(/<code([^>]*)>([\s\S]*?)<\/code>/g, (match, attrs, code) => {
const langMatch = attrs.match(/class="language-(\w+)"/);
const lang = langMatch ? langMatch[1] : 'plaintext';
const highlighted = hljs.highlight(code, { language: lang }).value;
return `<code${attrs}>${highlighted}</code>`;
});
}
})
]
});
const markdownText = ref('# Showdown Vue 示例\n**加粗文本**');
const htmlContent = ref('');
const render = () => {
htmlContent.value = converter.makeHtml(markdownText.value);
};
onMounted(() => render());
</script>
三、渲染优化与注意事项
1. 解决 XSS 安全风险
直接使用 innerHTML 可能导致 XSS 攻击。解决方案:
- 用 DOMPurify 净化 HTML(适合原生 JS/showdown):
import DOMPurify from 'dompurify';
const html = marked.parse(markdownText);
const safeHtml = DOMPurify.sanitize(html);
preview.innerHTML = safeHtml;
- React 项目优先用 react-markdown(默认安全),Vue 项目可配合 vue-dompurify-html 指令。
2. 样式美化:复用成熟 CSS 库
推荐直接引入现成样式库,实现 GitHub 风格等排版:
- github-markdown-css(最常用):
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/github-markdown-css/github-markdown.min.css">
使用时给预览区添加 markdown-body 类。
3. 大文档渲染性能优化
若渲染超长 Markdown,可能导致页面卡顿。优化方案:
- 分片渲染:只渲染当前可视区域内容;
- 懒加载图片:替换为
loading="lazy"格式; - 缓存解析结果:对相同的 Markdown 文本缓存解析后的 HTML。
四、常见场景选型建议
| 项目场景 | 推荐库 | 核心原因 |
|---|---|---|
| 原生 JS / 小项目 | marked.js | 轻量、速度快、学习成本低 |
| React 项目 | React-Markdown | 组件化、安全无 XSS、插件丰富 |
| Vue 项目 | showdown.js + vue-dompurify-html | 配置灵活、支持 Vue 指令 |
| 企业级文档 / 复杂语法 | showdown.js | 扩展能力强、支持自定义语法 |
| 静态站点(如博客) | Next.js/VuePress 内置 | 无需手动配置,支持 SSR/SSG |
五、总结
前端渲染 Markdown 的核心是选对库并做好配置:
- 简单场景用 marked.js 快速实现,React 项目优先 React-Markdown;
- 需复杂扩展时,搭配对应的插件(remark-gfm/rehype-katex);
- 始终关注安全(XSS)和性能(大文档优化),避免直接使用未净化的 innerHTML;
- 样式美化优先复用成熟 CSS 库,减少重复开发。
