首頁 > 軟體

umi外掛開發仿dumi專案實現markdown檔案轉為頁面

2023-01-28 18:02:53

引言

前面我們已經成功將.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檔案轉頁面的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com