JS Compiler

@next/mdx :底层使用MDX (基于unified) 编译 MDX → JS

MDX 源文件
   ↓ @mdx-js/mdx 解析(基于 micromark/remark)
MDAST (Markdown AST)
   ↓ mdast-util-to-hast(remark → rehype 过渡)
HAST (HTML AST)
   ↓ rehype 插件处理 HTML 节点
   ↓ hast-util-to-estree(HTML AST → JS AST)
JSX / React.createElement 代码
   ↓ 编译为 JS 模块
React 组件
   ↓ 使用 mdx-components.tsx 里提供的组件替换默认标签 
HTML DOM

Markdown (.md / .mdx)
  ↓ 解析(remark-parse / micromark;此处也会应用「语法类」remark 插件like remark-gfm)
MDAST(已生成)
  ↓ 「变换类」remark 插件在 MDAST 上运行(增删改节点, 锚点、TOC、链接重写)
  ↓ mdast-util-to-hast / remark-rehype
HAST
  ↓ rehype 插件在 HAST 上运行 (标签/属性/结构/代码高亮)
  ↓(hast-util-to-estree / to-jsx)
JSX / JS 模块(供 React 使用)

remarkrehype 都是 JavaScript 里的AST(抽象语法树)处理框架,但处理的对象和用途不同

工具 处理的文件类型 AST 类型
remark Markdown(.md, .mdx 中的 Markdown 部分) MDAST (Markdown AST)
rehype HTML(包括 Markdown 转换后的 HTML) HAST(HTML AST)

Global styles and components

使用 mdx-components.tsx,映射发生在“编译成 JSX 之后、React 渲染之前/之中”

Local styles and components

import Welcome from '@/markdown/welcome.mdx'
 
function CustomH1({ children }) {
  return <h1 style={{ color: 'blue', fontSize: '100px' }}>{children}</h1>
}
 
const overrideComponents = {
  h1: CustomH1,
}
 
export default function Page() {
  return <Welcome components={overrideComponents} />
}

Rust Compiler

  experimental: {
    mdxRs: true,
  }

Installation