創建一個 remark 插件來提取 MDX 閱讀時間
一個指導如何創建一個 remark 插件,使在將 MDX 文件作為 ES 模塊導入時可用的閱讀時間數據。
Remark 是一個功能強大的 markdown 處理器,可以用來創建自定義插件以轉換 markdown 內容。當使用 remark 解析 markdown 文件時,內容會被轉換成一個抽象語法樹 (AST),並可以使用插件來操作。
為了提供更好的用戶體驗,通常會顯示文章的預估閱讀時間。在本指南中,我們將創建一個 remark 插件,從 MDX 文件中提取閱讀時間數據,並在將 MDX 文件作為 ES 模塊導入時使其可用。
開始
首先我們來創建一個 MDX 文件:
假設我們使用 Vite 作為打包器,並使用官方的 @mdx-js/rollup
插件來轉換 MDX 文件,因此我們可以將 MDX 文件導入作為一個 ES 模塊。Vite 配置應該如下所示:
如果我們將 MDX 文件導入為一個 ES 模塊,內容將是一個物件,其中 default
屬性包含編譯的 JSX。例如:
將會產生:
一旦我們有了這樣的輸出,我們就可以準備創建 remark 插件。
創建 remark 插件
我們來看看需要做什麼來實現目標:
- 將 MDX 內容提取為文本以進行閱讀時間計算。
- 計算閱讀 時間。
- 將閱讀時間數據附加到 MDX 內容,以便在將 MDX 文件作為 ES 模塊導入時使其可用。
幸運的是,已經有庫可以幫助我們計算閱讀時間和基本的 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 內容,當導入 MDX 文件作為 ES 模塊時,將產生以下輸出:
如果需要更改閱讀時間數據的名稱,可以更新 Identifier
節點的 name
屬性。
TypeScript 支持
為了使插件對開發人員更加友好,我們可以做最後一步,增強 MDX 類型定義:
現在,當導入 MDX 文件時,TypeScript 將識別 readingTime
屬性:
結論
我希望這個指南能幫助你在使用 MDX 文件時有更好的體驗。通過這個 remark 插件,你可以直接使用閱讀時間數據,甚至可以利用 ESM 樹搖動來提高性能。