umi插件開發(fā)仿dumi項目實現(xiàn)markdown文件轉(zhuǎn)為頁面
引言
前面我們已經(jīng)成功將.md文件通過import加載到react組件中,并能拿到文件內(nèi)容進行展示。但是點擊markdown的導航鏈接還是會報錯:

這個報錯和前面的報錯有點相似,只是前面是無法解析鏈接,這里是無法解析對象。
處理導入錯誤
在react渲染頁面時,是調(diào)用一個個渲染函數(shù)來渲染頁面,我們來對比一下button頁和markdown頁加載頁面的bundle對比一下

button頁面導出的是一個Button函數(shù),返回的是創(chuàng)建該頁面的代碼

markdown導出的是一個js對象
而報錯提示我們markdown也應該導出為一個類或函數(shù),否則無法識別,所以下一步,我們就需要將這個帶有markdown正文的js對象轉(zhuǎn)換為react渲染函數(shù)。
loader返回渲染函數(shù)
我們前面通過自定義loader,將markdown轉(zhuǎn)為js對象導入,那么我們能不能將markdown對象轉(zhuǎn)為react渲染函數(shù),直接交給react渲染呢?我們直接將loader改成返回一個react函數(shù)組件
// /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
重啟后發(fā)現(xiàn)又報錯了

添加react處理loader
上面的錯誤依然很熟悉,說無法解析返回的字符串,還告訴我們可能要添加其他loader來處理返回值。
umi默認配置的babel-loader可以用來處理react組件,我們將其添加到解析鏈中,注意babel的執(zhí)行順序是反的,所以要先寫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文件就會先經(jīng)過md-loader轉(zhuǎn)為react組件字符串,接著使用babel-loader轉(zhuǎn)換為可執(zhí)行渲染函數(shù)。
再次啟動可以看到markdown文件內(nèi)容已經(jīng)能被渲染出來

用ts來寫loader
前面說了我們目前只能用js來寫loader,但是我們可以用一些小技巧,先繞過這個限制,使得不需要編譯也能使用ts來寫loader。讓webpack還是加載原來的組件,但是原來的代碼只做個代理,實際執(zhí)行代碼可以用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
創(chuàng)建新的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插件開發(fā)仿dumi項目實現(xiàn)markdown文件轉(zhuǎn)為頁面的詳細內(nèi)容,更多關于umi markdown文件轉(zhuǎn)頁面的資料請關注腳本之家其它相關文章!
相關文章
Javascript調(diào)用XML制作連動下拉列表框
Javascript調(diào)用XML制作連動下拉列表框...2006-06-06

