基于MDX的在线编译文档方案
基于MDX的在线文档实时编译方案
一、什么是MDX?
MDX 是一种用于编写 Markdown 和 JSX 内容的格式,其全称是 “Markdown for JSX”。它结合了 Markdown 的简洁易用与 JSX(JavaScript XML)的强大功能,使得开发者可以在 Markdown 文档中直接插入并使用 React 组件。这种格式特别适合于构建内容丰富的文档或博客,同时需要一部分动态、交互性组件的项目。
-
结合 Markdown 和 JSX: 你可以在一个文件中同时使用 Markdown 的简洁语法和 JSX 的灵活组件,使得编写内容和展示组件更加方便和一致。
-
动态交互: 由于可以在 MDX 中使用 React 组件,开发者能够轻松地添加交互性元素,比如按钮、图表、表单等,这对于需要动态内容的文档或网站特别有用。
-
易于集成: MDX 可以与很多静态网站生成器(如 Gatsby 和 Next.js)集成,使开发者能够在现代框架中轻松使用它。
-
拓展性强: 由于 MDX 本质上是 JavaScript,可以利用 JavaScript 的生态系统进行扩展,比如使用额外的插件来处理自定义的需求。
总结:Markdown与Jsx的结合体,可以在md文档的基础上加入各类动态React组件,可用来实现动态文档。
二、工作流程
1. 工作流程拆解
- 其核心提供了
jsx-runtime
依赖,并通过evaluate
&compile
方法,在线将mdx文档
编译为可渲染React组件
或可执行js文件
。 - mdx支持将文档编译为多种格式的产物,也支持定制各类文档主题,编辑器等,搭配起来可以实现非常不错的效果。
2. 依赖安装
下面将通过一个实际案例,梳理MDX工作的过程与原理(需要在任意React项目中进行)
npm i @mdx-js/mdx @mdx-js/react --save-dev
2. 编写编辑器组件
import React, { useState } from 'react';
import { Splitter, Card, Input, Typography } from 'antd';
import MdxPreview from './MdxPreview';
import defaultMDX from './defaultMDX.md';const { Title } = Typography;function App() {const [mdxValue, setMdxValue] = useState(defaultMDX);return (<div style={{ padding: '20px' }}><Cardtitle={<Title level={2}>MDX Runtime Edit Demo</Title>}style={{ border: '1px solid #f0f0f0' }}><Splitter style={{ height: '80vh' }}><Splitter.Panel defaultSize='40%' min='20%' max='70%' style={{ height: '100%' }}><Input.TextAreastyle={{fontFamily: 'monospace',fontSize: '14px',}}value={mdxValue}onChange={({ target: { value } }) => {setMdxValue(value);}}rows={40}/></Splitter.Panel><Splitter.Panel style={{ height: '100%' }}><divstyle={{border: '1px dashed #d9d9d9',boxSizing: 'border-box',padding: '20px 30px',overflow: 'auto',backgroundColor: '#fff',}}><MdxPreview mdxValue={mdxValue} /></div></Splitter.Panel></Splitter></Card></div>);
}export default App;
3. 编写渲染组件
import React, { useEffect, useState } from 'react';
import { message, Typography } from 'antd';
import * as antdComponents from 'antd';
import * as runtime from 'react/jsx-runtime';
import { evaluate, compile } from '@mdx-js/mdx';const { Title, Text } = Typography;function MdxPreview({ mdxValue }) {const [Content, setContent] = useState(null);const [error, setError] = useState(null);/*** MDX核心渲染方法*/const renderMDX = async () => {try {setError(null);// 将MDX文档构建为.js文件const compileResult = await compile(mdxValue, {});// 将MDX文档编译为可执行组件const { default: MDXContent } = await evaluate(mdxValue, {...runtime,development: false,});setContent(() => MDXContent);} catch (error) {console.error('Error processing MDX:', error);setError(error.message);message.error('MDX 编译错误,请检查语法');}};useEffect(() => {renderMDX();}, [mdxValue]);return (<>{error ? (<div style={{ color: 'red' }}><Title level={4}>错误信息:</Title><pre>{error}</pre></div>) : Content ? (<Content// 注入Antd所有组件components={{...antdComponents,}}/>) : (<Text type='secondary'>Loading...</Text>)}</>);
}export default MdxPreview;
3. 实现效果
在左侧修改任意内容,右侧均会实时渲染
三、Mdxeditor编辑器解决方案
- 提供成熟的编辑器&渲染组件
- 提供多种工具与插件,可以灵活配置编辑器
- 支持jsx、sandbox等插件,组件渲染能力非常强
官网:https://mdxeditor.dev/editor/demo