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 使用)

remark 和 rehype 都是 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