在維護 Astro 靜態網站時,內容集合(Content Collections)的 frontmatter 格式一致性是確保網站正常構建的關鍵。本文介紹如何使用 check-all-content.mjs 腳本來系統化檢查和修復內容文件格式問題。
問題背景
當 Astro 網站突然出現 id.endsWith is not a function 或類似的構建錯誤時,通常是由於內容文件的 frontmatter 格式問題所致。常見問題包括:
- 字符串字段缺少引號
- 字段類型不正確(如應為數組卻為字符串)
- 日期格式不規範
- 特殊字符未正確轉義
解決方案:check-all-content.mjs
腳本功能
check-all-content.mjs 是一個全面的檢查工具,能夠:
- 系統性掃描所有內容文件
- 識別格式問題並提供詳細錯誤信息
- 建議修復方案並可自動執行修復
基本使用方法
1. 創建檢查腳本
// Mountos Code Lab: check-all-content.mjs
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
console.log('🔍 系統性檢查所有內容文件...\n');
const blogDir = './src/content/blog';
const slugDirs = fs.readdirSync(blogDir, { withFileTypes: true })
.filter(item => item.isDirectory())
.map(item => item.name);
console.log(`找到 ${slugDirs.length} 個文章目錄\n`);
let totalProblems = 0;
for (const slug of slugDirs) {
const filePath = path.join(blogDir, slug, 'index.md');
if (!fs.existsSync(filePath)) {
console.log(`❌ ${slug}: 缺少 index.md`);
totalProblems++;
continue;
}
try {
const content = fs.readFileSync(filePath, 'utf8');
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatterMatch) {
console.log(`❌ ${slug}: 缺少 frontmatter`);
totalProblems++;
continue;
}
const data = yaml.load(frontmatterMatch[1]);
const fileProblems = [];
// 檢查必需字段
if (!data.title || typeof data.title !== 'string') {
fileProblems.push('title 問題');
}
if (!data.description || typeof data.description !== 'string') {
fileProblems.push('description 問題');
}
if (!data.pubDate) {
fileProblems.push('pubDate 問題');
}
if (fileProblems.length > 0) {
console.log(`⚠️ ${slug}: ${fileProblems.join(', ')}`);
totalProblems++;
} else {
console.log(`✅ ${slug}: 格式正確`);
}
} catch (error) {
console.log(`❌ ${slug}: ${error.message}`);
totalProblems++;
}
}
console.log(`\n📊 總共發現 ${totalProblems} 個問題`);
// [Mountos Code Lab](https://mountos.com/code)2. 運行檢查
node check-all-content.mjs進階功能:自動修復
對於常見問題,可以擴展腳本實現自動修復:
// fix-common-issues.mjs
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
console.log('🔧 自動修復常見問題...\n');
const blogDir = './src/content/blog';
const slugDirs = fs.readdirSync(blogDir, { withFileTypes: true })
.filter(item => item.isDirectory())
.map(item => item.name);
let fixedCount = 0;
for (const slug of slugDirs) {
const filePath = path.join(blogDir, slug, 'index.md');
try {
const content = fs.readFileSync(filePath, 'utf8');
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
if (!frontmatterMatch) continue;
let data = yaml.load(frontmatterMatch[1]);
let modified = false;
// 自動修復字段類型
if (data.title && typeof data.title !== 'string') {
data.title = String(data.title);
modified = true;
}
if (data.description && typeof data.description !== 'string') {
data.description = String(data.description);
modified = true;
}
if (modified) {
const newFrontmatter = '---\n' + yaml.dump(data).trim() + '\n---';
const newContent = content.replace(/^---\n[\s\S]*?\n---/, newFrontmatter);
fs.writeFileSync(filePath, newContent, 'utf8');
fixedCount++;
console.log(`✅ ${slug}: 已修復`);
}
} catch (error) {
console.log(`❌ ${slug}: 修復失敗`);
}
}
console.log(`\n🎉 完成!修復了 ${fixedCount} 個文件`);實際應用案例
案例:修復缺少引號的標題
問題文件:
---
title: 這是一個標題: 包含冒號
description: 描述內容
author: Mountos.com
pubDate: 2024-01-01
---修復後:
---
title: "這是一個標題: 包含冒號"
description: "描述內容"
author: Mountos.com
pubDate: 2024-01-01
---案例:修復數組字段
問題文件:
---
title: "文章標題"
tags: 單一標籤 # 應該是數組
---修復後:
---
title: "文章標題"
tags: ["單一標籤"]
---集成到工作流程
1. 預提交檢查(Git Hook)
在 .git/hooks/pre-commit 中添加:
#!/bin/bash
echo "檢查內容文件格式..."
node check-all-content.mjs
if [ $? -ne 0 ]; then
echo "請先修復內容文件格式問題"
exit 1
fi2. CI/CD 集成
在 GitHub Actions 工作流中:
- name: 檢查內容格式
run: node check-all-content.mjs最佳實踐建議
- 定期檢查:在每次內容更新後運行檢查腳本
- 自動化修復:對於可自動修復的問題,使用修復腳本
- 團隊協作:確保所有內容編輯者了解 frontmatter 格式規範
- 版本控制:將檢查腳本納入版本控制,方便團隊共享
總結
check-all-content.mjs 是一個強大的工具,能夠幫助 Astro 網站維護者:
- 快速定位內容格式問題
- 預防構建失敗
- 保持內容集合的一致性
- 提高團隊協作效率
通過將此工具集成到開發工作流程中,可以顯著減少因內容格式問題導致的網站構建失敗,確保網站的穩定運行。
使用命令:
- 檢查問題:node check-all-content.mjs
- 自動修復:node fix-common-issues.mjs
- 驗證修復結果:npm run build


發佈留言