umi插件開發(fā)仿dumi項(xiàng)目實(shí)現(xiàn)markdown文件轉(zhuǎn)為頁面
引言
前面我們已經(jīng)成功將.md
文件通過import加載到react組件中,并能拿到文件內(nèi)容進(jìn)行展示。但是點(diǎn)擊markdown
的導(dǎo)航鏈接還是會(huì)報(bào)錯(cuò):
這個(gè)報(bào)錯(cuò)和前面的報(bào)錯(cuò)有點(diǎn)相似,只是前面是無法解析鏈接,這里是無法解析對(duì)象。
處理導(dǎo)入錯(cuò)誤
在react
渲染頁面時(shí),是調(diào)用一個(gè)個(gè)渲染函數(shù)來渲染頁面,我們來對(duì)比一下button
頁和markdown
頁加載頁面的bundle對(duì)比一下
button頁面導(dǎo)出的是一個(gè)Button
函數(shù),返回的是創(chuàng)建該頁面的代碼
markdown導(dǎo)出的是一個(gè)js對(duì)象
而報(bào)錯(cuò)提示我們markdown
也應(yīng)該導(dǎo)出為一個(gè)類或函數(shù),否則無法識(shí)別,所以下一步,我們就需要將這個(gè)帶有markdown正文的js
對(duì)象轉(zhuǎn)換為react渲染函數(shù)。
loader返回渲染函數(shù)
我們前面通過自定義loader,將markdown轉(zhuǎn)為js對(duì)象導(dǎo)入,那么我們能不能將markdown對(duì)象轉(zhuǎn)為react渲染函數(shù),直接交給react渲染呢?我們直接將loader改成返回一個(gè)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)又報(bào)錯(cuò)了
添加react處理loader
上面的錯(cuò)誤依然很熟悉,說無法解析返回的字符串,還告訴我們可能要添加其他loader來處理返回值。
umi
默認(rèn)配置的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') // 用默認(rèn)帶的babel-loader來處理react組件 .use('babel-loader') .loader(babelInUmi.loader) .options(babelInUmi.options) .end() .use('md-loader') .loader(loaderPath) return memo; });
完成配置后,markdown
文件就會(huì)先經(jīng)過md-loader
轉(zhuǎn)為react
組件字符串,接著使用babel-loader
轉(zhuǎn)換為可執(zhí)行渲染函數(shù)。
再次啟動(dòng)可以看到markdown
文件內(nèi)容已經(jīng)能被渲染出來
用ts來寫loader
前面說了我們目前只能用js來寫loader,但是我們可以用一些小技巧,先繞過這個(gè)限制,使得不需要編譯也能使用ts來寫loader。讓webpack還是加載原來的組件,但是原來的代碼只做個(gè)代理,實(shí)際執(zhí)行代碼可以用ts來寫:
改變?cè)瓉淼膌oader
// /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àng)目實(shí)現(xiàn)markdown文件轉(zhuǎn)為頁面的詳細(xì)內(nèi)容,更多關(guān)于umi markdown文件轉(zhuǎn)頁面的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Javascript調(diào)用XML制作連動(dòng)下拉列表框
Javascript調(diào)用XML制作連動(dòng)下拉列表框...2006-06-06JavaScript 對(duì)象詳細(xì)整理總結(jié)
這篇文章主要介紹了JavaScript 對(duì)象詳細(xì)整理總結(jié)的相關(guān)資料,需要的朋友可以參考下2016-09-09微信小程序 判斷手機(jī)號(hào)的實(shí)現(xiàn)代碼
這篇文章主要介紹了微信小程序 判斷手機(jī)號(hào)的實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04本地存儲(chǔ)localStorage設(shè)置過期時(shí)間示例詳解
這篇文章主要為大家介紹了本地存儲(chǔ)localStorage設(shè)置過期時(shí)間示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01