建立一個 remark 插件來提取 MDX 閱讀時間
指南以創建一個 remark 插件,使在將 MDX 文件作為 ES 模組導入時,閱讀時間數據可用。
Remark 是一個強大的 markdown 處理器,可以用來創建自定義插件以轉換 markdown 內容。在用 remark 解析 markdown 文件時,內容會轉換為一個抽象語法樹(AST),可以使用插件進行操作。
為了提供更好的用戶體驗,通常會顯示文章的預計閱讀時間。在本指南中,我們將創建一個 remark 插件,從 MDX 文件中提取閱讀時間數據,並在作為 ES 模組導入 MDX 文件時使其可用。
開始
讓我們從創建一個 MDX 文件開始:
假設我們使用 Vite 作為打包工具,使用官方的 @mdx-js/rollup
插件來轉換 MDX 文件,因此我們可以將 MDX 文件作為 ES 模組進行導入。Vite 的配置應如下所示:
如果我們將 MDX 文件作為 ES 模組進行導入,內容將是一個包含 default
屬性的對象,該屬性包含已編譯的 JSX。例如:
將產生:
一旦我們有了這樣的輸出,我們就可以準備創建 remark 插件了。
創建 remark 插件
讓我們看看為了實現目標需要做什麼:
- 提取 MDX 內容以供閱讀時間計算。
- 計算閱讀時間。
- 將閱讀時間數據附加到 MDX 內容上,使其在作為 ES 模組導入 MDX 文件時可用。
幸運的是,已經有庫可以幫助我們進行閱讀時間計算和基本的 AST 操作:
reading-time
用於計算閱讀時間。mdast-util-to-string
用於將 MDX AST 轉換為文本。estree-util-value-to-estree
用於將閱讀時間數據轉換為 ESTree 節點。
如果你是 TypeScript 用戶,你可能還需要安裝這些包以獲取類型定義:
@types/mdast
用於 MDX 根節點類型定義。unified
用於插件類型定義。
只要我們安裝了這些包,就可以開始創建插件:
如我們所見,插件只是將 MDX 內容提取為文本並計算閱讀時間。現在我們需要將閱讀時間數據附加到 MDX 內容上,這看起來並不那麼簡單。但是如果我們看看其他很棒的庫,比如 remark-mdx-frontmatter,我們可以找到一種方法來實現:
注意代碼中的 type: 'mdxjsEsm'
。這是一種用於 序列化 MDX ESM 的節點類型。上面的代碼使用名稱 readingTime
將閱讀時間數據附加到 MDX 內容上,這將在作為 ES 模組導入 MDX 文件時產生以下輸出:
如果你需要更改閱讀時間數據的名稱,可以更新 Identifier
節點的 name
屬性。
TypeScript 支援
為了讓插件對開發者更友好,可以通過增強 MDX 類型定義進行最後的修飾:
現在,在導入 MDX 文件時,TypeScript 將識別 readingTime
屬性:
結論
希望本指南能幫助你在使用 MDX 文件時獲得更好的體驗。有了這個 Remark 插件,你可以直接使用閱讀時間數據,甚至可以利用 ESM 的樹搖優化來提高性能。