umi插件开发仿dumi项目加载markdown文件实现详解

这篇文章主要为大家介绍了umi插件开发仿dumi项目加载markdown文件实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

前面章节中我们已经顺利将tsx组件转换为页面展示,但是目前提供的功能和umi的约定式路由功能差不多,接下来我们将实现将markdown文件转换为页面展示。

为什么不能直接展示markdown

我们前面所使用的页面写法都是react组件式写法,umi通过webpack将react组件打包,这是react项目通用的模式。由于webpack不认识markdown文件,所以我们直接引入markdown文件会报错。所以我们只需要让webpack认识markdown,通过自定义loader来加载markdown文件即可。

chainWebpack

umi提供chainWebpack插件api,通过 webpack-chain 的方式修改 webpack 配置。

webpack loader

loader是用于webpack解析文件的工具,不同的loader可以解析不同类型的文件,使其解析的内容可被其他模块使用。

我们需要解析markdown文件,那么就需要写一个能认识markdown文件的loader,它的功能就是识别.md文件并将文件内容解析成对象返回给import这个文件的代码使用。

实现过程

新建插件

跟前面一样,我们新建一个插件来处理文件解析:

// /src/features/compile.ts import type { IApi } from 'umi'; export default (api: IApi) => { api.describe({ key: 'domi:compile' }); api.chainWebpack(async (memo) => { const loaderPath = require.resolve('../loaders/markdown/loader.js'); memo.module // 通过链式处理,向`webpack`添加了一条名为`domi-md`的处理规则 .rule('domi-md') // 该规则用于处理`.md`文件 .test(/\.md$/) // 给这个loader取个名字 .use('md-loader') // loader的路径 .loader(loaderPath) return memo; }); }; 

新建loader

接下来创建loader文件,注意这里loader要使用js文件,因为webpack无法直接解析ts类型的loader,第一个入参是文件内容的字符串形式,我们先直接返回。

// /src/loaders/markdown/loader.js function mdLoader(context) { return context } module.exports = mdLoader 

为什么`dumi`的loader是用`ts`写的?

因为在`dumi`开发环境下,先将`ts`文件转成了`js`,`webpack`在运行时其实还是加载的`js`形式的loader。

dumi: 编译 => 启动umi(webpack) => 开发环境

domi: 启动umi(webpack) => 开发环境 

新建测试文档

// /docs/markdown.md # 我是markdown 

运行项目

启动项目可以看到markdown文件已经正确解析到导航栏中了

点开链接一看,啥也没有,报错了

解决文件加载类型错误

看上面的报错信息,意思好像是懒加载的组件元素类型错误,打开请求列表看看加载了什么东西

应该就是这里在加载markdown文件时,只导出了个url链接,我们打开链接看看

这里就返回了markdown内容,看来目前不能直接从页面打开。

我们换一种方式,在jsx中直接导入这个文件看看:

// /docs/index.tsx import react from 'react' import md from './markdown.md' const Home = () => { return (
hello domi! {md}
) } export default Home

刷新页面可以看到,import进来的对象确实只是一个地址,那我们直接放个iframe来显示:

// /docs/index.tsx import react from 'react' import md from './markdown.md' const Home = () => { return (<>
hello domi!