introduction
MDX是markdown的超级让你能够直接在markdown文件中编写 JSX,它是一种有用的方式去增加动态交互能力,并且在你的内容中内嵌组件 …帮助你引导页面到现实生活 …
Next.js 支持MDX(通过大量不同的含义),这里罗列了一些方式能够集成MDX到Next.js 项目中 …
为什么使用MDX
在markdown中写作是一种直观的方式进行内容编写,它简洁的语法,一旦适配,能够让你写入同时具有超强可读性和可维护性的内容,因为你能够在markdown中使用HTML
元素,这样当装饰你的markdown 页面的时候你能够获得创新 …
然而,由于markdown 本质上是静态内容,你不能基于用户的交互性创建动态内容.. 这里MDX它携带了一种能力让你能够创建直接并在标记中使用React 组件,这打开了更多可能性(当构建具有交互性页面) …
MDX 插件
内部MDX使用备注和重新炒作???, 备注是一个markdown 处理器(由插件生态系统支持的),这个插件生态系统能够让我们解析代码,转换HTML
元素,改变语法,提取前置物以及更多 …
rehype 是一个HTML
处理器,同样是插件生态系统提供支持的,类似于remark,这些插件能够让你维护,清理,编译以及配置所有类型的数据、元素、内容 ..
为了使用一个来自remark或者rehype的插件,你需要增加它们到MDX 包配置 …
next/mdx
这个@next/mdx
包配置在next.config.js
文件中,它的资源数据来源于本地文件,允许你使用.mdx
扩展创建页面,直接使用在/pages
目录中 …
在Next.js 中配置@next/mdx
以下步骤罗列了如何在Next.js 项目中配置next/mdx
- 安装需要的包
npm install @next/mdx @mdx-js/loader
- 确保这些包存在且配置去支持顶级的
.mdx
页面,以下增加了一个options
对象key 允许我们传递插件 ..
// next.config.js
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [],
rehypePlugins: [],
},
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'md', 'mdx'],
})
- 在
/pages
中创建一个新的MDX 页面
- /pages
- my-mdx-page.mdx
- package.json
使用组件,布局以及自定义元素
现在我能够直接在MDX页面中导入React组件 ..
import { MyComponent } from 'my-components'
# My MDX page
This is a list in markdown:
- One
- Two
- Three
Checkout my React component:
<MyComponent/>
前置器
前置器是一个YAML (类似于 key/value 键值对能够用来存储一个页面的数据) … @next/mdx
默认并没有支持前置器(尽管这里存在许多能够增加前置器到你的MDX内容的解决方案,例如 gray-matter) ….
为了使用@next/mdx
访问页面的元数据,你能够在.mdx
文件中暴露一个元数据对象 …
export const meta = {
author: 'Rich Haines'
}
# My MDX page
例如
==
..... metadata
==
这些 需要通过前置器进行解析 …
布局
为了增加布局到MDX页面中,创建一个新的组件并导入它到MDX 页面中,然后你能够在布局组件中包装这个MDX 页面 …
import { MyComponent, MyLayoutComponent } from 'my-components'
export const meta = {
author: 'Rich Haines'
}
# My MDX Page with a Layout
This is a list in markdown:
- One
- Two
- Three
Checkout my React component:
<MyComponent/>
export default = ({ children }) => <MyLayoutComponent meta={meta}>{children}</MyLayoutComponent>
可以看到这种写法有一点怪异:
并没有将自己传入,而是通过children 属性进行布局渲染 …
自定义元素
使用markdown 令人愉快的一个方面是,它能够映射到HTML
元素,能够快速编写且非常直观 …
# H1 heading
## H2 heading
This is a list in markdown:
- One
- Two
- Three
然后会生成以下内容
<h1>H1 heading</h1>
<h2>H2 heading</h2>
<p>This is a list in markdown:</p>
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
如果你想要装饰你自己的元素让它有一种另类的感觉,你能够通过短代码进行传递,这些可以是你自己的自定义组件然后映射到HTML
元素上,为了这样做,你需要使用MDXProvider
并传递一个组件对象作为属性,组件对象中的每一个对象key 都可以映射为HTML
元素名 …
例如:
// pages/index.js
import { MDXProvider } from '@mdx-js/react'
import Image from 'next/image'
import { Heading, Text, Pre, Code, Table } from 'my-components'
const ResponsiveImage = (props) => (
<Image alt={props.alt} layout="responsive" {...props} />
)
const components = {
img: ResponsiveImage,
h1: Heading.H1,
h2: Heading.H2,
p: Text,
code: Pre,
inlineCode: Code,
}
export default function Post(props) {
return (
<MDXProvider components={components}>
<main {...props} />
</MDXProvider>
)
}