Skip to navigation

MDX 按需

本指南介绍如何使用 @mdx-js/mdx 在服务器上编译 MDX 并在客户端上运行结果。 某些框架(例如 Next.js 和 Remix)可以轻松地在服务器和客户端之间分配工作。 例如,使用它可以在服务器上按需完成大部分工作,而不是在构建时完成,然后将结果数据传递给客户端,最终在客户端使用它。

这类似于人们有时使用 mdx-bundlernext-mdx-remote 的用途,但 MDX 也支持它。

快速示例

在服务器上:

server.js
import {compile} from '@mdx-js/mdx'

const code = String(await compile('# hi', {
  outputFormat: 'function-body',
  /* …otherOptions */
}))
// To do: send `code` to the client somehow.

在客户端:

client.js
import {run} from '@mdx-js/mdx'
import * as runtime from 'react/jsx-runtime'

const code = '' // To do: get `code` from server somehow.

const {default: Content} = await run(code, {...runtime, baseUrl: import.meta.url})

Content 现在是 MDXContent 组件,你可以像平常一样在框架中使用它(请参阅 § 使用 MDX)。

更多信息可在 @mdx-js/mdxcompilerun 的 API 文档中找到。 对于其他用例,你还可以使用 evaluate,它可以同时编译和运行。

注意: MDX 不是打包器(esbuild、webpack 和 Rollup 是打包器): 你无法从 MDX 字符串中的服务器导入其他代码并获得一个很好缩小的包左右。

Next.js 示例

有些框架允许你将服务器和客户端代码编写在一个文件中,例如 Next。

pages/hello.js
import {compile, run} from '@mdx-js/mdx'
import {Fragment, useEffect, useState} from 'react'
import * as runtime from 'react/jsx-runtime'

export default function Page({code}) {
  const [mdxModule, setMdxModule] = useState()
  const Content = mdxModule ? mdxModule.default : Fragment

  useEffect(function () {
    ;(async function () {
      setMdxModule(await run(code, {...runtime, baseUrl: import.meta.url}))
    })()
  }, [code])

  return <Content />
}

export async function getStaticProps() {
  const code = String(
    await compile('# hi', {
      outputFormat: 'function-body',
      /* …otherOptions */
    })
  )
  return {props: {code}}
}
MDX 中文网 - 粤ICP备13048890号