本指南介绍如何创建一个remark插件,在将MDX文件作为ES模块导入时,使阅读时间数据可用。
Remark是一个强大的Markdown处理器,可以用来创建自定义插件以转换Markdown内容。当使用remark解析Markdown文件时,内容会被转换成抽象语法树(AST),可以通过插件进行操作。
为了提供更好的用户体验,通常会显示文章的估计阅读时间。在本指南中,我们将创建一个remark插件,从MDX文件中提取阅读时间数据,并在将MDX文件作为ES模块导入时使其可用。
开始
首先创建一个MDX文件:
假设我们使用Vite作为打包工具,并且使用官方的@mdx-js/rollup
插件来转换MDX文件,因此我们可以将MDX文件作为ES模块导入。Vite的配置应该如下所示:
如果我们将MDX文件作为ES模块导入,内容将是一个对象,其中default
属性包含编译后的JSX。例如:
将会得到:
一旦我们有了这样的输出,我们就准备好创建remark插件了。
创建remark插件
让我们看看实现目标需要做些什么:
- 将MDX内容提取为文本以计算阅读时间。
- 计算阅读时间。
- 将阅读时间数据附加到MDX内容中,使其在将MDX文件作为ES模块导入时可用。
幸运的是,已经有库可以帮助我们计算阅读时间和进行基本的AST操作:
reading-time
用于计算阅读时间。mdast-util-to-string
用于将MDX AST转换为文本。estree-util-value-to-estree
用于将阅读时间数据转换为ESTree节点。
如果你使用TypeScript,你可能还需要安装这些包以获得类型定义:
@types/mdast
用于MDX根节点类型定义。unified
用于插件类型定义。
只要我们安装了这些包,就可以开始创建插件:
如我们所见,插件简单地将MDX内容提取为文本并计算阅读时间。现在我们需要将阅读时间数据附加到MDX内容中,这看起来不是很简单。但如果我们查看其他很棒的库,比如 remark-mdx-frontmatter,我们可以找到一种方法来实现:
注意代码中的type: 'mdxjsEsm'
。这是一个用于 序列化MDX ESM的节点类型。上面的代码使用名称readingTime
将reading time
数据附加到MDX内容中,当将MDX文件作为ES模块导入时将得到如下输出:
如果你需要更改阅读时间数据的名称,可以更新Identifier
节点的name
属性。
TypeScript支持
为了使插件对开发者更加友好,我们可以通过增强MDX类型定义进行最后的调整:
现在,当导入MDX文件时,TypeScript将识别readingTime
属性:
结论
希望本指南能帮助你在处理MDX文件时获得更好的体验。通过这个remark插件,你可以直接使用阅读时间数据,甚至利用ESM树摇优化性能。