背景
想在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就行。