最近使用React渲染Markdown,进行了一些简单的探索,和大家分享下相关经验。
基本的Markdown能力
当下有许多成熟的Markdown库,如 marked、react-markdown等,这里我采用的是react-markdown。因其与React有更好的结合。
react-markdown地址:https://www.npmjs.com/package/react-markdown
其用法也比较简单:
1 2 3 4 5 6 7 8
import React from 'react' import Markdown from 'react-markdown' export default props => ( <Markdown source={props.content} /> )
代码语法高亮
如果不做任何配置,React-Markdown会使用 <pre>
包裹Markdown中的代码块。
这样虽然也能正常显示,但是没有了语法高亮的功能,不够美观。
好在React-Markdown中提供了自定义renderer的功能,可以自定义渲染逻辑。
首先,在React-Markdown中配置下使用自定义渲染引擎:
1 2 3 4 5 6 7 8 9 10 11
import React from 'react' import Markdown from 'react-markdown' const CodeBlock = ({ language, value }) => <pre>{value}</pre> export default props => ( <Markdown source={props.content} renderers={{ code: CodeBlock }} /> )
这里我们配置了使用CodeBlock
来渲染代码块,目前还是在使用pre进行渲染。
然后,再在CodeBlock
中加上语法高亮的支持。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
import React from 'react' import Markdown from 'react-markdown' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism' const CodeBlock = ({ language, value }) => ( <SyntaxHighlighter language={language} style={codeStyle}> {value} </SyntaxHighlighter> ) export default props => ( <Markdown source={props.content} renderers={{ code: CodeBlock }} /> )
这里使用了react-syntax-highlighter
库来做语法高亮支持。
它支持多套主题,具体可配置项参考其官方文档。
React Syntax Highlighter地址: https://www.npmjs.com/package/react-syntax-highlighter
流程图支持
有一套名为Mermaid的流程图库,可在Markdown中直接使用,但是目前在各平台的支持度不同步,React-Markdown中也没有默认支持它。
使用Mermaid可以在Markdown中使用指令画出流程图、类图、甘特图、状态图等多种图表,方便好用,具体用法可参考其官方网站。
Mermaid官方网站:https://mermaid-js.github.io/mermaid/#/
Mermaid是一套JS库,可以在网页中直接加载使用,我们可以稍微修改下CodeBlock
组件,对其进行支持。
首先,在页面中加载mermaid.min.js,并启用自动渲染功能。
可直接将其写入 html 文件中:
1 2
<script src="//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js"></script> <script>mermaid.initialize({startOnLoad:true});</script>
如果写在React中,则需要处理下{}字符:
1 2
<script src='//unpkg.com/mermaid@8.4.8/dist/mermaid.min.js' /> <script>mermaid.initialize({'{startOnLoad: true}'});</script>
在开启startOnLoad: true
之后,Mermaid会自动处理className中带有mermaid
的tag。
因此,CodeBlock
中可以做如下的修改:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
import React from 'react' import Markdown from 'react-markdown' import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter' import { solarizedlight as codeStyle } from 'react-syntax-highlighter/dist/cjs/styles/prism' const CodeBlock = ({ language, value }) => ( language === 'mermaid' ? return <div className='mermaid'>{value}</div> : <SyntaxHighlighter language={language} style={codeStyle}> {value} </SyntaxHighlighter> ) export default props => ( <Markdown source={props.content} renderers={{ code: CodeBlock }} /> )
至此,大功告成。
最后,放个示例mermaid,大家看看效果: