前言

记录一下最近看dumi 源码的笔记,你可以从笔记中学习到

  1. webpack loader 的编写
  2. webpack plugin 的编写
  3. markdown源文件如何转换成 html
  4. markdnwn 中编写 react demo 组件时,渲染成对应的组件
  5. markdown 增强,添加了 <embed />, <Container /> 等组件
  6. esbuild 插件等
  7. 约定式路由

目录

src 下的目录结构

.
├── assetParsers   # DUMI DEMO 相关,即可以通过 <code src='./index.tsx' /> 等方式加载
│   ├── atom.ts 
│   └── block.ts   # esbuild 相关,处理DUMI DEMO 对应依赖
├── client          # Dumi 客户端相关,内置api,以及内置页面等,主题
│   ├── pages       # 内置页面组件,404 等
│   ├── theme-api   # Dumi 内置api
│   ├── theme-default # dumi 主题
├── features         # dumi 启用的插件
│   ├── assets.ts    #  https://d.umijs.org/plugin/api#modifyassetsmetadata 
│   ├── autoAlias.ts    # 给src 下目录添加alias, 当我们写组件时允许通过包名的方式导入他 
│   ├── compile
│   │   ├── babelLoaderCustomize.ts
│   │   └── index.ts
│   ├── configPlugins
│   │   ├── index.ts
│   │   └── schema.ts
│   ├── derivative.ts
│   ├── exportStatic.ts
│   ├── exports.ts     # 导出dumi 的方法,指的是src/client/theme-api 
│   ├── locales.ts
│   ├── meta.ts       # 从markdown源文件 解析获取toc, 标题,路由,tabs 等 
│   ├── parser.ts
│   ├── routes.ts    
│   ├── sideEffects   #  添加sideEffects,比如.dumi/tmp 目录,.dumi/tmp-production
│   │   ├── docSideEffectsWebpackPlugin.ts
│   │   └── index.ts
│   ├── sitemap.ts
│   ├── tabs.ts
│   └── theme
│       ├── ThemeDemo.tsx
│       ├── index.ts
│       └── loader.ts
├── index.ts
├── loaders      ## markdown 转html 相关,具体是一个loader
│   ├── markdown
│   │   ├── index.ts
│   │   └── transformer
│   │       ├── index.ts
│   │       ├── rehypeDemo.ts
│   │       ├── rehypeDesc.ts
│   │       ├── rehypeEnhancedTag.ts
│   │       ├── rehypeImg.ts
│   │       ├── rehypeIsolation.ts
│   │       ├── rehypeJsxify.ts
│   │       ├── rehypeLink.ts
│   │       ├── rehypeRaw.ts
│   │       ├── rehypeSlug.ts
│   │       ├── rehypeStrip.ts
│   │       ├── rehypeText.ts
│   │       ├── remarkContainer.ts
│   │       ├── remarkEmbed.ts
│   │       └── remarkMeta.ts
│   ├── page
│   │   └── index.ts
│   └── pre-raw
│       └── index.ts
├── preset.ts    # dumi 启动的插件,具体插件是上面feature目录
├── registerMethods.ts
├── service      #  命令行 相关 即npm scripts 等命令
│   ├── cli.ts
│   ├── constants.ts
│   ├── dev.ts
│   ├── forkedDev.ts
│   ├── printHelp.ts
│   └── service.ts
├── techStacks
│   └── react.ts
├── types.ts
└── utils.ts

插件

dumi 源码中可以看到使用了非常多的hook, 比如modifyConfigmodifyDefaultConfigmodifyPaths, onGenerateFiles, modifyRoutes 等, 具体可以查看

流程

  1. 注册 feature/compile 插件, 通过loader 去解析markdown 文件,Markdown 文件的元信息,如标题、示例代码等。
  2. 具体由 unified 库调用对应的markdown 解析插件收集到的信息,放入 VFile 中,跟随解析后得到的html 一并返回
  3. 通过 收集到的文件的原信息去生成 tmp 文件,比如 路由文件(./dumi/tmp/core/route.tsx, meta文件(./dumi/tmp/dumi/meta)
  4. 最后就是 通过loader, 返回react 代码