unified插件开发【仿dumi项目】- 开发环境搭建

简介

大家好,本章是【仿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
复制代码

运行代码后会有如下报错: image.png

处理ESM导入错误

由于unified是用纯ESM导出的包,而node的环境是用CommonJS,如果我们在ts中直接导入则会提示无法支持require导入ESM包的错误。

使用tsx替换ts-nodetsx可以帮助我们0配置解决不同类型的包导入,甚至可以混用,也就是说连tsconfig.json都不需要了。

# 也可以全局安装,看自己喜欢用哪种
npm install --save-dev tsx
复制代码

在package.json中添加运行命令"dev": "tsx ./src/index"

运行npm run dev可以看到如下结果:

image.png

创建一个插件

后面我们会完成一个自定义插件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')
复制代码

可以看到插件中打印的内容已经输出到控制台,说明插件引入成功 image.png

至此我们已经成功搭建开发环境,下一节将搭建测试环境

分类:
前端