在維護 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
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 fi
2. 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
以實際行動支持獨立觀點,與我們一同走得更遠
每一篇條理清晰的分析、每一次不隨波逐流的觀察,背後都是對真實與品質的堅持。我們拒絕內容農場與演算法流量綁架,堅持自由獨立的客觀發聲。
維持高品質的原創寫作與獨立營運,需要持續的實質力量。您可以選擇一次性贊助或每月定期支持,透過 Google 安全結帳,與我們一同守護這份深刻與清醒。
由 Google 安全處理付款 · 可隨時於 Google 帳戶管理或取消



留言板
為節省資源,留言將於捲動至此處或點擊按鈕後載入。