如何让Docusaurus一次性检测并告知所有缺失的图片?
解决Docusaurus构建时一次性显示所有缺失图片的问题
Docusaurus默认构建逻辑遇到单篇文档中第一张缺失图片就会终止报错,无法一次性展示所有缺失资源。可以通过以下几种方案实现批量检查并输出所有缺失图片:
方法一:自定义Docusaurus插件捕获所有缺失资源
编写一个轻量自定义插件,遍历所有文档文件、解析图片引用,批量校验文件存在性后统一抛出所有错误:
- 在项目根目录创建
plugins/check-all-images.js文件,写入以下代码:
const fs = require('fs'); const path = require('path'); const { visit } = require('unist-util-visit'); const remarkParse = require('remark-parse'); const unified = require('unified'); module.exports = function (context) { const { siteDir } = context; return { name: 'check-all-images', async postBuild() { const docsPath = path.join(siteDir, 'docs'); const missingImages = []; // 递归遍历所有文档文件 function walkDir(dir) { const files = fs.readdirSync(dir); for (const file of files) { const fullPath = path.join(dir, file); const stats = fs.statSync(fullPath); if (stats.isDirectory()) { walkDir(fullPath); } else if (fullPath.endsWith('.md') || fullPath.endsWith('.mdx')) { checkFileImages(fullPath); } } } // 检查单个文档中的图片引用 function checkFileImages(filePath) { const content = fs.readFileSync(filePath, 'utf8'); // 解析Markdown格式的图片引用 const tree = unified().use(remarkParse).parse(content); visit(tree, 'image', (node) => { const imagePath = path.join(path.dirname(filePath), node.url); if (!fs.existsSync(imagePath)) { missingImages.push(`Image ${path.relative(siteDir, imagePath)} used in ${path.relative(siteDir, filePath)} not found.`); } }); // 解析MDX中的img标签 const imgTagRegex = /<img[^>]+src=["']([^"']+)["']/g; let match; while ((match = imgTagRegex.exec(content)) !== null) { const imagePath = path.join(path.dirname(filePath), match[1]); if (!fs.existsSync(imagePath)) { missingImages.push(`Image ${path.relative(siteDir, imagePath)} used in ${path.relative(siteDir, filePath)} not found.`); } } } walkDir(docsPath); // 输出所有缺失图片并终止构建 if (missingImages.length > 0) { console.error('\n=== 所有缺失的图片 ==='); missingImages.forEach(err => console.error(err)); process.exit(1); } } }; };
- 在
docusaurus.config.js中注册该插件:
module.exports = { // 保留原有配置 plugins: [require('./plugins/check-all-images')], };
方法二:在CI/CD脚本中提前执行批量检查
在Docusaurus构建命令前,添加一个独立脚本完成图片校验,避免进入Docusaurus构建流程后中断:
以Linux/macOS为例,创建根目录文件check-images.sh:
#!/bin/bash SITE_DIR=$(pwd) MISSING=() # 遍历所有MD/MDX文档 find "$SITE_DIR/docs" -type f \( -name "*.md" -o -name "*.mdx" \) | while read -r FILE; do # 提取Markdown格式图片路径 grep -E '!\[.*?\]\((.*?)\)' "$FILE" | sed -E 's/!\[.*?\]\((.*?)\)/\1/' | while read -r IMG_PATH; do FULL_IMG_PATH=$(realpath "$(dirname "$FILE")/$IMG_PATH") if [ ! -f "$FULL_IMG_PATH" ]; then MISSING+=("Image $(realpath --relative-to="$SITE_DIR" "$FULL_IMG_PATH") used in $(realpath --relative-to="$SITE_DIR" "$FILE") not found.") fi done # 提取MDX中img标签的src路径 grep -E '<img[^>]+src=["'\'']([^"'\'' ]+)["'\'' ]' "$FILE" | sed -E 's/.*src=["'\'']([^"'\'' ]+)["'\'' ].*/\1/' | while read -r IMG_PATH; do FULL_IMG_PATH=$(realpath "$(dirname "$FILE")/$IMG_PATH") if [ ! -f "$FULL_IMG_PATH" ]; then MISSING+=("Image $(realpath --relative-to="$SITE_DIR" "$FULL_IMG_PATH") used in $(realpath --relative-to="$SITE_DIR" "$FILE") not found.") fi done done # 输出错误并终止流程 if [ ${#MISSING[@]} -gt 0 ]; then echo -e "\n=== 所有缺失的图片 ===" printf '%s\n' "${MISSING[@]}" exit 1 fi
然后在CI/CD脚本中调整执行顺序:
bash check-images.sh && npm run build
方法三:修改Docusaurus源码(不推荐)
找到Docusaurus负责资源校验的核心模块(如@docusaurus/utils/lib/validation.js),将原本遇到第一个错误就抛出的逻辑,改为收集所有错误后统一输出。但这种方案依赖特定版本,升级Docusaurus后需要重新修改,维护成本较高,仅推荐临时应急使用。
内容的提问来源于stack exchange,提问作者Keith Palmer Jr.
相关产品推荐
相关产品推荐

