背景
想在Nuxt3中讀取markdown以渲染文章。
分析
靜態檔案一般是放在public中的,但是官方文件中寫明:
而且,在SSR階段(伺服器渲染),nuxt無法透過fetch來訪問public裡的內容(雖然不推薦,但是客戶端的js是可以透過fetch直接請求到檔案的)。
過程
nuxt提供了一個content模組,這是一個檔案系統的CMS,雖然似乎沒有讀取檔案的功能,但是可以直接渲染出markdown,再配合上css樣式,我覺得其實也沒太多問題。
xx中文網上,顯示未適配nuxt3,但是實際上是這個網站太落後了,看到官網上就沒有這個提示,甚至feature上面還特別寫明瞭nuxt3支援。
不得不說,很多官網後面加個cn的網站都很不負責,很多英文不翻譯,很多情況下還不如直接看官網,省的看著看著是英文浪費額外的時間。(所以說學英語確實重要)
https://nuxt.com.cn/modules/content
@nuxt/content使用示例
推薦檢視官網
https://content.nuxt.com/get-started/installation
npx nuxi module add content
在專案根目錄下建立目錄content,這個目錄代表content模組中填寫路徑時的根目錄
以下為引用示例,ContentDoc會直接渲染出markdown(使用md檔案)
<ContentDoc path="/markdown/about/about" />
到這裡已經成功了,接下來就是樣式了,這個自己解決把
左側為真實檔案路徑,右側是我們寫程式碼時使用的引用路徑,細節去看文件即可。
傳統fs模組
import fs from 'fs/promises';
// 注意此處的判斷,nuxt預設採用通用渲染,這意味著setup部分的程式碼,會被伺服器以及客戶端分別執行一次,而客戶端上沒有我們要讀取的檔案(而且也沒有node的api),因此不加判斷就會報錯。
if(!import.meta.client){
const markdownPath = 'content/1.markdown/1.about/about.md';
fs.readFile(markdownPath, 'utf8').then((data:any) => {
console.log('檔案內容:', data);
});
}
需要特別注意的是,使用fs模組,nuxt是無感知的(路徑之類的他又不知道),這就導致build時不會把檔案打包,需要手動複製一份過去。
比如我上面寫的路徑為content,我需要把content複製一份放到.output目錄中(也就是伺服器根目錄,ecosystem.config.cjs、server、public所在的路徑)
結語
我個人還是傾向於使用nuxt content,雖然不是真正的讀取檔案,但是與nuxt結合得更加緊密,不需要手動移檔案。所以說,需求比較小的直接用content就行。