引言
前面我们已经成功将.md
文件通过import加载到react组件中,并能拿到文件内容进行展示。但是点击markdown
的导航链接还是会报错:
这个报错和前面的报错有点相似,只是前面是无法解析链接,这里是无法解析对象。
处理导入错误
在react
渲染页面时,是调用一个个渲染函数来渲染页面,我们来对比一下button
页和markdown
页加载页面的bundle对比一下
button页面导出的是一个Button
函数,返回的是创建该页面的代码
markdown导出的是一个js对象
而报错提示我们markdown
也应该导出为一个类或函数,否则无法识别,所以下一步,我们就需要将这个带有markdown正文的js
对象转换为react渲染函数。
loader返回渲染函数
我们前面通过自定义loader,将markdown转为js对象导入,那么我们能不能将markdown对象转为react渲染函数,直接交给react渲染呢?我们直接将loader改成返回一个react
函数组件
// /src/loaders/markdown/loader.js
function mdLoader(content) {
return `
import react from 'react'
const content = ${JSON.stringify(content)};
const Markdown = () => {
return (<div>{content}</div>)
}
export default Markdown
`
}
module.exports = mdLoader
重启后发现又报错了
添加react处理loader
上面的错误依然很熟悉,说无法解析返回的字符串,还告诉我们可能要添加其他loader来处理返回值。
umi
默认配置的babel-loader可以用来处理react组件,我们将其添加到解析链中,注意babel的执行顺序是反的,所以要先写babel-loader
再写md-loader
:
api.chainWebpack(async (memo) => {
const babelInUmi = memo.module.rule('src').use('babel-loader').entries();
const loaderPath = require.resolve('../loaders/markdown/loader.js');
memo.module
.rule('domi-md')
.test(/\.md$/)
.type('javascript/auto')
// 用默认带的babel-loader来处理react组件
.use('babel-loader')
.loader(babelInUmi.loader)
.options(babelInUmi.options)
.end()
.use('md-loader')
.loader(loaderPath)
return memo;
});
完成配置后,markdown
文件就会先经过md-loader
转为react
组件字符串,接着使用babel-loader
转换为可执行渲染函数。
再次启动可以看到markdown
文件内容已经能被渲染出来
用ts来写loader
前面说了我们目前只能用js来写loader,但是我们可以用一些小技巧,先绕过这个限制,使得不需要编译也能使用ts来写loader。让webpack还是加载原来的组件,但是原来的代码只做个代理,实际执行代码可以用ts来写:
改变原来的loader
// /src/loaders/markdown/loader.js
function mdLoader(content) {
const options = this.getOptions({ 'handler': true })
return options.handler.apply(this, [content])让
}
module.exports = mdLoader
创建新的loader
// /src/loaders/markdown/index.ts
export default function mdLoader(this: any, content: string) {
return `
import react from 'react'
const content = ${JSON.stringify(content)};
const Markdown = () => {
return (<div>{content}</div>)
}
export default Markdown
`
}
配置webpack
// /src/features/compile.ts
import MdLoader from '../loaders/markdown/index'
...
.use('md-loader')
.loader(loaderPath)
.options({
handler: MdLoader
})
...
完整代码可查看feature/render-markdown
以上就是umi插件开发仿dumi项目实现markdown文件转为页面的详细内容,更多关于umi markdown文件转页面的资料请关注编程网其它相关文章!