简介
大家好,本章是【仿umi项目】的第二部分unified插件开发。
第一部分已经介绍了如何通过自定义umi插件来加载Markdown文件,但是在处理Markdown仅是简单的将文本渲染到页面上,离我们真正需要的渲染markdown还差一步。本章将开始一个新的模块,仿照dumi
的解析方式,使用unified
来将Markdown字符串转换为react-jsx
字符串。
学习本节后,我们可以对unified
的整体流程及其插件开发有更深入的了解。
为啥不使用`react-markdown`直接渲染?
`react-markdown`也是基于`unified`来开发的,所以理论上直接使用也可以。
本节我们还是以dumi的设计方式为基础学习,有兴趣的同学可以自行探究。
复制代码
学习本节需要先对unified有基础的认识,可以参考unified - 一个用于处理markdown的解析器 - 掘金 (juejin.cn)先对unified整体大致有个了解。
开发计划
由于dumi
使用的unified
插件是直接写到项目中,个人感觉不太方便学习和调试,所以这里我们单独开一个项目来专门写解析markdown的插件,并提供一个统一接口供项目使用。项目完成后发布为npm包直接给dumi
使用。
项目采用最小依赖,不使用father
等工具,用最原始的方法来封装库,这样可以暴露出更多问题,使用father
的话有些问题会被掩盖不利于学习。
我们的这个项目需要实现以下几个要点:
- 开发环境需要简单
- 使用typescript来编写代码库
- 使用jest来搭建测试环境
- 实现
dumi
中unified相关功能 - 打包成npm包
- 能替换
dumi
中的unified并正常运行
开发环境搭建
初始化项目和目录结构
# 项目名就叫这个吧
mkdir unified-md
# 代码放在这个目录中
mkdir unified-md/src
# 测试代码放在这个目录中
mkdir unified-md/test
# 初始化package.json
npm init -y
# 初始化typescript
tsc --init
复制代码
创建代码文件,引入unified
# 安装依赖
npm install unified remark-parse remark-stringify
复制代码
// /src/index.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
const res = unified()
.use(remarkParse)
.use(remarkStringify)
.processSync('# hello unified-md')
console.log(res)
复制代码
# 由于是ts我们用ts-node来运行
ts-node ./src/index.ts
复制代码
运行代码后会有如下报错:
处理ESM导入错误
由于unified是用纯ESM
导出的包,而node的环境是用CommonJS
,如果我们在ts中直接导入则会提示无法支持require导入ESM包的错误。
使用tsx替换ts-node
,tsx
可以帮助我们0配置解决不同类型的包导入,甚至可以混用,也就是说连tsconfig.json
都不需要了。
# 也可以全局安装,看自己喜欢用哪种
npm install --save-dev tsx
复制代码
在package.json中添加运行命令"dev": "tsx ./src/index"
运行npm run dev
可以看到如下结果:
创建一个插件
后面我们会完成一个自定义插件remark-footnote
,用于给markdown添加一个脚注,现在我们先创建个壳
// /src/remark/remark-footnote.ts
export default function remarkFootnote() {
return () => {
console.log("remarkFootnote")
}
}
复制代码
添加到unified处理流程中
// /src/index.ts
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
import remarkFootnote from "./remark/remarkFootnote";
const res = unified()
.use(remarkParse)
.use(remarkFootnote)
.use(remarkStringify)
.processSync('# hello unified-md')
复制代码
可以看到插件中打印的内容已经输出到控制台,说明插件引入成功
至此我们已经成功搭建开发环境,下一节将搭建测试环境