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.jsconst 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 pageThis is a list in markdown:- One- Two- ThreeCheckout 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 LayoutThis is a list in markdown:- One- Two- ThreeCheckout my React component:<MyComponent/>export default = ({ children }) => <MyLayoutComponent meta={meta}>{children}</MyLayoutComponent>
可以看到这种写法有一点怪异:
并没有将自己传入,而是通过children 属性进行布局渲染 …
自定义元素
使用markdown 令人愉快的一个方面是,它能够映射到HTML元素,能够快速编写且非常直观 …
# H1 heading## H2 headingThis 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.jsimport { 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>)}
