从相对目录中加载图片
默认图片必须放在 public 目录下,并在 mdx 中使用绝对目录访问,这对于 Markdown 编辑器来说十分不友好
举个例子,目录如下
1
2
3
4
5
6
|
├── content
│ └── docs
│ ├── index.assets
│ │ └── image-20260206.png
│ ├── index.mdx
│ └── test.mdx
|
1
|

|
此时,Markdown 编辑器可以正常展示图片,但是 fumadocs 就没办法正常加载图片了,如果将图片放在 public 目录下,并修改 index.mdx 的引入图片为:
1
|

|
这个时候 fumadocs 可以正常加载图片,Markdown 编辑器又加载不出图片了
那么,有没有两全其美的方法呢?有的兄弟有的
我们可以使用官方提供的 MDX Plugin:Remark Image,以支持从非 public 目录下访问图片
source.config.ts
1
2
3
4
5
6
7
|
export default defineConfig({
mdxOptions: {
remarkImageOptions: {
useImport: true, // 允许从非 public 的目录下读取图片
},
},
});
|
修改后,我们就可以使用相对路径,从类似 content/docs/index.assets 的目录下加载图片了,并且 fumadocs 也能正常渲染
根据环境替换图片路径
这里可以使用官方提供的图片缩放组件 ImageZoom,以优化体验
在传入 src 前,我们可以进行处理,根据环境判断是否使用 CDN 地址,并且为了避免硬编码地址,我们可以使用环境变量配置 CDN 地址
这里使用的是 WAKU 框架,公共变量需要以 WAKU_PUBLIC 开头,根据实际使用的框架自行修改变量名
[...slugs].tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<MDX
components={{
...defaultMdxComponents,
img: (props) => {
let newSrc = props.src;
if (import.meta.env.PROD) {
newSrc =
import.meta.env.WAKU_PUBLIC_ASSETS_HOST +
props.src +
'?fmt=webp';
}
return <ImageZoom src={newSrc} />;
},
}}
/>
|
构建时将图片放到指定目录方便上传
经过上面的配置,我们已经可以实现本地开发时从本地加载图片,构建后从 CDN 加载图片,但是由于我们的图片并不是全部放在 public 目录下,上传到对象存储中总归不太方便(可以写个 postbuild 脚本来自动化上传),这里提供一个解决方案
修改 vite 的配置,将图片放置到指定目录
waku.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
export default defineConfig({
vite: {
// we do this to avoid Vite from bundling React contexts and cause duplicated contexts conflicts.
optimizeDeps: {
exclude: ['fumadocs-ui', 'fumadocs-core', '@fumadocs/ui'],
},
plugins: [tailwindcss(), mdx(MdxConfig), tsconfigPaths()],
build: {
rollupOptions: {
output: {
assetFileNames: (assetInfo) => {
if (/\.(png|jpe?g|gif|svg|webp)$/.test(assetInfo.name || '')) {
return 'upload/[name]-[hash][extname]';
}
return 'assets/[name]-[hash][extname]';
},
},
},
},
} satisfies UserConfig as Config['vite'],
});
|
这样,build 后的图片就会被放置到 upload 目录下,我们只需要将该目录下的图片都上传到对象存储桶中就完美搞定了
如果 vite 中配置的目录是 upload/xxx ,那么在对象存储桶中也需要上传到一模一样的目录下
部署的时候由于用不到 upload/xxx 目录下的文件了,可以写个脚本来自动化删除,❗上传后再删除❗
验证
可以 build 后查看代码或运行后通过浏览器的 Devtool - Network 验证图片是否从 CDN 中加载