umi插件开发仿dumi项目加载markdown文件实现详解
umi插件开发仿dumi项目加载markdown文件实现详解
gridf 2023-01-30 10:07:30 阅读() 评论()
目录引言为什么不能直接展示markdownchainWebpackwebpack loader实现过程新建插件新建loader新建测试文档运行项目解决文件加载类型错误webpack ruletype解决错误引言前面章节中我们已经顺利将tsx组件转换为页面展示,但是目前提供的功能和umi的约定式路由功能差不多,接下来我们将实现将markdown文件转换为页面展示。为什么不能直接展示markdown我…
![](https://www.0419af.com/wp-content/uploads/2023/02/1675229070-46a309f1022ff0c.jpg)
目录引言为什么不能直接展示markdownchainWebpackwebpack loader实现过程新建插件新建loader新建测试文档运行项目解决文件加载类型错误webpack ruletype解决错误
引言
前面章节中我们已经顺利将tsx组件转换为页面展示,但是目前提供的功能和umi的约定式路由功能差不多,接下来我们将实现将markdown文件转换为页面展示。
为什么不能直接展示markdown
我们前面所使用的页面写法都是react组件式写法,umi通过webpack将react组件打包,这是react项目通用的模式。由于webpack不认识markdown文件,所以我们直接引入markdown文件会报错。所以我们只需要让webpack认识markdown,通过自定义loader来加载markdown文件即可。
chainWebpack
umi提供chainWebpack插件api,通过 webpack-chain 的方式修改>
webpack>
loader是用于webpack解析文件的工具,不同的loader可以解析不同类型的文件,使其解析的内容可被其他模块使用。
我们需要解析markdown文件,那么就需要写一个能认识markdown文件的loader,它的功能就是识别.md文件并将文件内容解析成对象返回给import这个文件的代码使用。
实现过程
新建插件
跟前面一样,我们新建一个插件来处理文件解析:
// /src/features/compile.tsimport 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.jsfunction 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文件已经正确解析到导航栏中了
![](https://www.0419af.com/wp-content/uploads/2023/02/1675229075-46a309f1022ff0c.jpg)
点开链接一看,啥也没有,报错了
解决文件加载类型错误
看上面的报错信息,意思好像是懒加载的组件元素类型错误,打开请求列表看看加载了什么东西
应该就是这里在加载markdown文件时,只导出了个url链接,我们打开链接看看
这里就返回了markdown内容,看来目前不能直接从页面打开。
我们换一种方式,在jsx中直接导入这个文件看看:
// /docs/index.tsximport react from ‘react’import md from ‘./markdown.md’const Home = () => { return (hello domi! {md})}export default Home
刷新页面可以看到,import进来的对象确实只是一个地址,那我们直接放个iframe来显示:
// /docs/index.tsximport react from ‘react’import md from ‘./markdown.md’const Home = () => { return ( hello domi! )}export default Home
哈哈终于显示出来了
webpack>
当然上面并不是我们想要的效果,从前面的尝试大概能判断出来是webpack在打包时并没有想我们想象那样能直接导出我们想要的对象。这时候我们就要使用webpack一个配置ruletype,告诉他我们想要将markdown文件import成一个包含正文内容的对象,而不是一个资源地址。
这里webpack将文件视为Resource资源,其将所有 .md 文件都发送到输出目录,并且其路径将被注入到 bundle中,与我们常使用的在jsx中导入图片等一样,具体可参考资源模块 | webpack 中文文档 (docschina.org)
要改变这一默认行为,只需要配置时改变资源类型即可
// /src/features/compile.jsapi.chainWebpack(async (memo) => { const loaderPath = require.resolve(‘../loaders/markdown/loader.js’); memo.module .rule(‘domi-md’) .test(/\.md$/) // 表示文件经过这个loader处理后转换为可导入的js模块 .type(‘javascript/auto’) .use(‘md-loader’) .loader(loaderPath) return memo;});
重启后运行,发现又报了另一个错误
解决错误
从报错上看,意思大概是.md文件在经过loader解析后,解析返回值失败,还告诉我们可能需要其他loader来处理返回值。
这个就比较好理解了,因为上面我们指定了经过loader处理后应该返回一个可导出的js模块,而我们目前loader只返回了markdown的正文内容,并不是js数据,所以我们只需要改动以下loader的返回值即可:
// /src/loaders/markdown/loader.jsfunction mdLoader(content) { return ` const content = ‘${JSON.stringify(content)}’ export default { content }; `}module.exports = mdLoader
此时经过loader处理后,将会导出一个带有content属性的对象,再改变一下导入展示的组件:
import react from ‘react’import md from ‘./markdown.md’const Home = () => { return (hello domi! {md.content})}export default Home
重启后可以看到如下所示,此时我们已经成功通过loader加载到markdown文件显示
以上就是umi插件开发仿dumi项目加载markdown文件实现详解的详细内容,更多关于umi插件加载markdown文件的资料请关注易采站长站其它相关文章!
本文来自网络,不代表站长之家-易采站长站-Easck.Com立场。
给这篇文章的作者打赏
微信扫一扫打赏
支付宝扫一扫打赏
×
打赏 赞
标签:文件 加载 插件 错误 组件