refactor: 移除旧式双文件配置支持

- 简化配置加载逻辑,仅支持模块化配置
- 移除所有处理旧式配置文件的代码
- 创建配置迁移脚本,便于用户从旧版本迁移
This commit is contained in:
Zuoling Rong
2025-05-05 03:30:13 +08:00
parent 297890315b
commit f3da13035f
7 changed files with 334 additions and 573 deletions

View File

@@ -36,22 +36,19 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: npm install run: npm install
# --- 书签处理步骤开始 --- # --- 书签处理步骤 ---
- name: Create bookmarks directory if not exists - name: Check for bookmark HTML files
run: mkdir -p bookmarks
- name: Check for bookmark files
id: check_bookmark_files id: check_bookmark_files
run: | run: |
if [ "$(find bookmarks -type f -name "*.html" 2>/dev/null)" ]; then if [ -d bookmarks ] && [ "$(find bookmarks -type f -name "*.html" 2>/dev/null)" ]; then
echo "found=true" >> $GITHUB_OUTPUT echo "found=true" >> $GITHUB_OUTPUT
echo "Found bookmark files to process" echo "Bookmark HTML files found, will process them."
else else
echo "found=false" >> $GITHUB_OUTPUT echo "found=false" >> $GITHUB_OUTPUT
echo "No bookmark files found" echo "No bookmark HTML files found, skipping bookmark processing."
fi fi
- name: Process bookmark file - name: Process bookmark files
if: steps.check_bookmark_files.outputs.found == 'true' if: steps.check_bookmark_files.outputs.found == 'true'
run: | run: |
echo "Processing bookmark files..." echo "Processing bookmark files..."
@@ -62,42 +59,57 @@ jobs:
run: | run: |
echo "Current directory contents:" echo "Current directory contents:"
ls -la ls -la
echo "Does bookmarks.user.yml exist?" echo "Checking config/user/pages directory:"
if [ -f bookmarks.user.yml ]; then if [ -d config/user/pages ]; then
echo "YES - bookmarks.user.yml exists" echo "Directory exists, listing contents:"
cat bookmarks.user.yml | head -n 10 ls -la config/user/pages/
if [ -f config/user/pages/bookmarks.yml ]; then
echo "✓ bookmarks.yml exists in config/user/pages/"
cat config/user/pages/bookmarks.yml | head -n 10
else
echo "✗ bookmarks.yml does not exist in config/user/pages/"
fi
else else
echo "NO - bookmarks.user.yml does not exist" echo "✗ config/user/pages directory does not exist"
fi fi
- name: Commit bookmarks.user.yml changes - name: Commit bookmark configuration changes
if: steps.check_bookmark_files.outputs.found == 'true' if: steps.check_bookmark_files.outputs.found == 'true'
run: | run: |
git config --local user.email "action@github.com" git config --local user.email "action@github.com"
git config --local user.name "GitHub Action (Bookmarks)" git config --local user.name "GitHub Action (Bookmarks)"
# Check if the file exists # Check if config/user/pages/bookmarks.yml exists
if [ -f bookmarks.user.yml ]; then if [ -f config/user/pages/bookmarks.yml ]; then
# Check if file is already tracked by git # Check if this is a new file or it has changes
if git ls-files --error-unmatch bookmarks.user.yml 2>/dev/null; then if git ls-files --error-unmatch config/user/pages/bookmarks.yml 2>/dev/null; then
echo "bookmarks.user.yml exists and is tracked by git" echo "config/user/pages/bookmarks.yml exists and is tracked by git"
# Check if it has changes # Check if it has changes
if ! git diff --quiet bookmarks.user.yml; then if ! git diff --quiet config/user/pages/bookmarks.yml; then
echo "bookmarks.user.yml has changes, committing..." echo "config/user/pages/bookmarks.yml has changes, committing..."
git add bookmarks.user.yml git add config/user/pages/bookmarks.yml
git commit -m "Update bookmarks.user.yml from imported bookmarks" git commit -m "Update bookmarks configuration from imported bookmarks"
else else
echo "No changes to bookmarks.user.yml" echo "No changes to bookmarks configuration"
fi fi
else else
echo "bookmarks.user.yml exists but is not tracked by git (new file)" echo "config/user/pages/bookmarks.yml exists but is not tracked by git (new file)"
git add bookmarks.user.yml git add config/user/pages/bookmarks.yml
git commit -m "Add bookmarks.user.yml from imported bookmarks" git commit -m "Add bookmarks configuration from imported bookmarks"
fi
# Also check for navigation file changes
if [ -f config/user/navigation.yml ]; then
if ! git diff --quiet config/user/navigation.yml; then
echo "config/user/navigation.yml has changes, committing..."
git add config/user/navigation.yml
git commit -m "Update navigation to include bookmarks page"
fi
fi fi
else else
echo "ERROR: bookmarks.user.yml does not exist! Bookmark processing may have failed." echo "ERROR: config/user/pages/bookmarks.yml does not exist! Bookmark processing may have failed."
echo "Current directory contents:" echo "Current directory contents:"
ls -la ls -la config/user/pages/ || echo "Directory does not exist"
fi fi
- name: Clean up processed bookmark files - name: Clean up processed bookmark files
@@ -130,14 +142,12 @@ jobs:
echo "Checking git status before pushing..." echo "Checking git status before pushing..."
git status git status
echo "Checking bookmarks.user.yml existence before pushing..." echo "Checking config/user/pages directory before pushing..."
if [ -f bookmarks.user.yml ]; then if [ -d config/user/pages ]; then
echo "bookmarks.user.yml exists with content:" echo "✓ config/user/pages directory exists"
ls -la bookmarks.user.yml ls -la config/user/pages/
echo "First 5 lines:"
head -n 5 bookmarks.user.yml
else else
echo "WARNING: bookmarks.user.yml does not exist before pushing!" echo "WARNING: config/user/pages directory does not exist before pushing!"
fi fi
echo "Pushing changes to repository..." echo "Pushing changes to repository..."

View File

@@ -1,79 +0,0 @@
# 自动生成的书签配置文件 - 请勿手动编辑
# 由bookmark-processor.js生成于 2025-05-01T13:43:27.486Z
# 若要更新请将新的书签HTML文件放入bookmarks/目录
title: 我的书签
subtitle: 从浏览器导入的书签收藏
categories:
- name: 技术资源
icon: fas fa-folder
sites:
- name: GitHub
url: https://github.com/
icon: fab fa-github
description: "从书签导入: GitHub"
- name: Stack Overflow
url: https://stackoverflow.com/
icon: fab fa-stack-overflow
description: "从书签导入: Stack Overflow"
- name: MDN Web Docs
url: https://developer.mozilla.org/
icon: fas fa-link
description: "从书签导入: MDN Web Docs"
- name: freeCodeCamp
url: https://www.freecodecamp.org/
icon: fas fa-link
description: "从书签导入: freeCodeCamp"
- name: LeetCode
url: https://leetcode.com/
icon: fas fa-link
description: "从书签导入: LeetCode"
- name: 社交媒体
icon: fas fa-folder
sites:
- name: Twitter
url: https://twitter.com/
icon: fab fa-twitter
description: "从书签导入: Twitter"
- name: LinkedIn
url: https://www.linkedin.com/
icon: fab fa-linkedin
description: "从书签导入: LinkedIn"
- name: Reddit
url: https://www.reddit.com/
icon: fab fa-reddit
description: "从书签导入: Reddit"
- name: Instagram
url: https://www.instagram.com/
icon: fab fa-instagram
description: "从书签导入: Instagram"
- name: 新闻与资讯
icon: fas fa-folder
sites:
- name: Hacker News
url: https://news.ycombinator.com/
icon: fas fa-link
description: "从书签导入: Hacker News"
- name: TechCrunch
url: https://techcrunch.com/
icon: fas fa-link
description: "从书签导入: TechCrunch"
- name: The Verge
url: https://www.theverge.com/
icon: fas fa-link
description: "从书签导入: The Verge"
- name: 工具
icon: fas fa-folder
sites:
- name: Notion
url: https://www.notion.so/
icon: fas fa-link
description: "从书签导入: Notion"
- name: Trello
url: https://trello.com/
icon: fab fa-trello
description: "从书签导入: Trello"
- name: Figma
url: https://www.figma.com/
icon: fas fa-link
description: "从书签导入: Figma"

View File

@@ -1,297 +0,0 @@
site:
title: 我的导航
description: 个人网络导航站
author: Your Name
favicon: favicon.ico
logo_text: 导航站
fonts:
title:
family: Poppins
weight: 600
source: google
subtitle:
family: Quicksand
weight: 500
source: google
body:
family: Noto Sans SC
weight: 400
source: google
profile:
title: Hello,
subtitle: Welcome to My Navigation
description: 导航菜单
navigation:
- name: 首页
icon: fas fa-home
id: home
active: true
- name: 项目
icon: fas fa-project-diagram
id: projects
- name: 文章
icon: fas fa-book
id: articles
- name: 朋友
icon: fas fa-users
id: friends
- name: 书签
icon: fas fa-bookmark
id: bookmarks
social:
- name: GitHub
url: https://github.com
icon: fab fa-github
- name: Telegram
url: https://t.me
icon: fab fa-telegram
- name: Twitter
url: https://twitter.com
icon: fab fa-twitter
- name: Steam
url: https://steam.com
icon: fab fa-steam
categories:
- name: 常用网站
icon: fas fa-star
sites:
- name: Linux.do
url: https://linux.do/
icon: fab fa-linux
description: 新的理想型社区
- name: Google
url: https://www.google.com
icon: fab fa-google
description: 全球最大的搜索引擎
- name: GitHub
url: https://www.github.com
icon: fab fa-github
description: 代码托管平台
- name: Stack Overflow
url: https://stackoverflow.com
icon: fab fa-stack-overflow
description: 程序员问答社区
- name: ChatGPT
url: https://chat.openai.com
icon: fas fa-robot
description: AI智能助手
- name: 学习资源
icon: fas fa-graduation-cap
sites:
- name: 哔哩哔哩
url: https://www.bilibili.com
icon: fas fa-play-circle
description: 视频学习平台
- name: 知乎
url: https://www.zhihu.com
icon: fas fa-question-circle
description: 问答社区
- name: 掘金
url: https://juejin.cn
icon: fas fa-book
description: 高质量技术社区
- name: LeetCode
url: https://leetcode.cn
icon: fas fa-code
description: 算法刷题平台
- name: 开发工具
icon: fas fa-tools
sites:
- name: VS Code
url: https://code.visualstudio.com
icon: fas fa-code
description: 强大的代码编辑器
- name: Postman
url: https://www.postman.com
icon: fas fa-paper-plane
description: API调试工具
- name: Git
url: https://git-scm.com
icon: fab fa-git-alt
description: 版本控制工具
- name: Docker
url: https://www.docker.com
icon: fab fa-docker
description: 容器化平台
- name: 设计资源
icon: fas fa-palette
sites:
- name: Figma
url: https://www.figma.com
icon: fab fa-figma
description: 在线设计工具
- name: Dribbble
url: https://dribbble.com
icon: fab fa-dribbble
description: 设计师社区
- name: Behance
url: https://www.behance.net
icon: fab fa-behance
description: 创意设计平台
- name: IconFont
url: https://www.iconfont.cn
icon: fas fa-icons
description: 图标资源库
- name: 在线工具
icon: fas fa-wrench
sites:
- name: JSON Editor
url: https://jsoneditoronline.org
icon: fas fa-code-branch
description: JSON在线编辑器
- name: Can I Use
url: https://caniuse.com
icon: fas fa-browser
description: 浏览器兼容性查询
- name: TinyPNG
url: https://tinypng.com
icon: fas fa-compress
description: 图片压缩工具
- name: Carbon
url: https://carbon.now.sh
icon: fas fa-code
description: 代码图片生成器
projects:
title: 我的项目
subtitle: 这里展示了我的一些个人项目和开源贡献
categories:
- name: 个人项目
icon: fas fa-code
sites:
- name: 个人导航站
icon: fas fa-compass
description: 一个简洁美观的个人导航页面
url: "#"
- name: Todo List
icon: fas fa-tasks
description: 基于Vue3的待办事项管理器
url: "#"
- name: 个人博客
icon: fas fa-blog
description: 使用Hexo搭建的技术博客
url: "#"
- name: 开源贡献
icon: fas fa-code-branch
sites:
- name: Project A
icon: fab fa-github
description: 开源项目贡献
url: "#"
- name: Project B
icon: fab fa-github
description: 开源项目贡献
url: "#"
articles:
title: 技术文章
subtitle: 分享我的技术文章和学习笔记
categories:
- name: 最新文章
icon: fas fa-pen
sites:
- name: Vue3最佳实践
icon: fab fa-vuejs
description: Vue3组合式API的使用技巧
url: "#"
- name: JavaScript进阶
icon: fab fa-js
description: JavaScript高级特性解析
url: "#"
- name: Git使用技巧
icon: fab fa-git-alt
description: Git常用命令和工作流
url: "#"
- name: Docker入门
icon: fab fa-docker
description: Docker基础知识和实践
url: "#"
- name: 学习笔记
icon: fas fa-book
sites:
- name: React Hooks
icon: fab fa-react
description: React Hooks最佳实践
url: "#"
- name: Node.js实战
icon: fab fa-node-js
description: Node.js服务端开发笔记
url: "#"
- name: CSS技巧
icon: fab fa-css3
description: CSS常用技巧总结
url: "#"
- name: 数据库设计
icon: fas fa-database
description: 数据库架构和优化笔记
url: "#"
- name: 源码解析
icon: fas fa-code
sites:
- name: Vue源码解析
icon: fab fa-vuejs
description: Vue.js核心原理解析
url: "#"
- name: React原理
icon: fab fa-react
description: React核心机制解析
url: "#"
friends:
title: 友情链接
subtitle: 优秀的博主和朋友们
categories:
- name: 技术博主
icon: fas fa-user-friends
sites:
- name: 小明的博客
icon: fas fa-code
description: 全栈开发工程师,分享技术心得
url: "#"
- name: 小红的前端
icon: fas fa-paint-brush
description: 专注前端开发与设计
url: "#"
- name: 小张的后端
icon: fas fa-server
description: 分享后端开发经验
url: "#"
- name: 小李的移动端
icon: fas fa-mobile-alt
description: 移动应用开发专家
url: "#"
- name: 技术社区
icon: fas fa-laptop-code
sites:
- name: GitHub
icon: fab fa-github
description: 开源代码托管平台
url: https://github.com
- name: Stack Overflow
icon: fab fa-stack-overflow
description: 程序员问答社区
url: https://stackoverflow.com
- name: 掘金
icon: fas fa-book
description: 高质量技术社区
url: https://juejin.cn
- name: V2EX
icon: fas fa-comments
description: 创意工作者社区
url: https://v2ex.com
- name: 休闲娱乐
icon: fas fa-coffee
sites:
- name: 哔哩哔哩
icon: fas fa-play-circle
description: 视频弹幕网站
url: https://www.bilibili.com
- name: 知乎
icon: fas fa-question-circle
description: 问答社区
url: https://www.zhihu.com
- name: 豆瓣
icon: fas fa-film
description: 文艺生活社区
url: https://www.douban.com
- name: 网易云音乐
icon: fas fa-music
description: 音乐平台
url: https://music.163.com

View File

@@ -9,7 +9,9 @@
"dev": "node src/generator.js && serve dist", "dev": "node src/generator.js && serve dist",
"clean": "rm -rf dist", "clean": "rm -rf dist",
"build": "npm run clean && npm run generate", "build": "npm run clean && npm run generate",
"restructure": "node restructure.js" "restructure": "node restructure.js",
"migrate-config": "node src/migrate-config.js",
"import-bookmarks": "node src/bookmark-processor.js"
}, },
"keywords": [ "keywords": [
"navigation", "navigation",

View File

@@ -4,12 +4,12 @@ const yaml = require('js-yaml');
// 书签文件夹路径 - 使用相对路径 // 书签文件夹路径 - 使用相对路径
const BOOKMARKS_DIR = 'bookmarks'; const BOOKMARKS_DIR = 'bookmarks';
// 输出配置文件路径 - 使用相对路径 // 模块化配置目录
const OUTPUT_FILE = 'bookmarks.user.yml'; const CONFIG_USER_DIR = 'config/user';
// 模块化页面配置目录
const CONFIG_USER_PAGES_DIR = path.join(CONFIG_USER_DIR, 'pages');
// 模块化输出配置文件路径 // 模块化输出配置文件路径
const MODULAR_OUTPUT_FILE = 'config/user/pages/bookmarks.yml'; const MODULAR_OUTPUT_FILE = path.join(CONFIG_USER_PAGES_DIR, 'bookmarks.yml');
// 默认书签配置文件路径 - 使用相对路径
const DEFAULT_BOOKMARKS_FILE = 'bookmarks.yml';
// 模块化默认书签配置文件路径 // 模块化默认书签配置文件路径
const MODULAR_DEFAULT_BOOKMARKS_FILE = 'config/_default/pages/bookmarks.yml'; const MODULAR_DEFAULT_BOOKMARKS_FILE = 'config/_default/pages/bookmarks.yml';
@@ -197,10 +197,10 @@ function generateBookmarksYaml(bookmarks) {
// 添加注释 // 添加注释
const yamlWithComment = const yamlWithComment =
`# 自动生成的书签配置文件 - 用户自定义版本 `# 自动生成的书签配置文件
# 由bookmark-processor.js生成于 ${new Date().toISOString()} # 由bookmark-processor.js生成于 ${new Date().toISOString()}
# 若要更新请将新的书签HTML文件放入bookmarks/目录 # 若要更新请将新的书签HTML文件放入bookmarks/目录
# 注意此文件会覆盖bookmarks.yml中的同名配置 # 此文件使用模块化配置格式位于config/user/pages/目录下
${yamlString}`; ${yamlString}`;
@@ -211,58 +211,96 @@ ${yamlString}`;
} }
} }
// 更新现有config.yml中的导航添加书签页面 // 更新导航以包含书签页面
function updateConfigWithBookmarks() { function updateNavigationWithBookmarks() {
// 传统配置文件 console.log('Checking navigation configuration for bookmarks page...');
const configFile = 'config.yml';
const userConfigFile = 'config.user.yml';
// 模块化配置文件 // 模块化配置文件
const modularNavFile = 'config/_default/navigation.yml'; const modularUserNavFile = path.join(CONFIG_USER_DIR, 'navigation.yml');
const modularUserNavFile = 'config/user/navigation.yml'; const modularDefaultNavFile = 'config/_default/navigation.yml';
let navigationUpdated = false; let navigationUpdated = false;
// 按优先级顺序尝试更新导航配置 // 按优先级顺序尝试更新导航配置
// 1. 最高优先级: 模块化用户导航配置 // 1. 首选: 模块化用户导航配置
if (fs.existsSync(modularUserNavFile)) { if (fs.existsSync(modularUserNavFile)) {
navigationUpdated = updateNavigationFile(modularUserNavFile); navigationUpdated = updateNavigationFile(modularUserNavFile);
if (navigationUpdated) { if (navigationUpdated) {
console.log(`Updated modular user navigation file: ${modularUserNavFile} (highest priority)`); console.log(`Updated modular user navigation file: ${modularUserNavFile}`);
} }
} }
// 2. 其次: 模块化默认导航配置
// 2. 次高优先级: 传统用户配置 else if (fs.existsSync(modularDefaultNavFile)) {
if (!navigationUpdated && fs.existsSync(userConfigFile)) { // 如果用户导航文件不存在,我们需要先创建它,然后基于默认文件更新
navigationUpdated = updateTraditionalConfig(userConfigFile); try {
if (navigationUpdated) { // 读取默认导航文件
console.log(`Updated legacy user config file: ${userConfigFile}`); const defaultNavContent = fs.readFileSync(modularDefaultNavFile, 'utf8');
const defaultNav = yaml.load(defaultNavContent);
// 确保目录存在
if (!fs.existsSync(CONFIG_USER_DIR)) {
fs.mkdirSync(CONFIG_USER_DIR, { recursive: true });
}
// 写入用户导航文件
fs.writeFileSync(modularUserNavFile, defaultNavContent, 'utf8');
console.log(`Created user navigation file based on default: ${modularUserNavFile}`);
// 更新新创建的文件
navigationUpdated = updateNavigationFile(modularUserNavFile);
if (navigationUpdated) {
console.log(`Updated newly created navigation file: ${modularUserNavFile}`);
}
} catch (error) {
console.error(`Error creating user navigation file:`, error);
} }
} }
// 3. 如果都不存在,创建一个基本的导航文件
// 3. 次低优先级: 模块化默认导航 else {
if (!navigationUpdated && fs.existsSync(modularNavFile)) { try {
navigationUpdated = updateNavigationFile(modularNavFile); // 确保目录存在
if (navigationUpdated) { if (!fs.existsSync(CONFIG_USER_DIR)) {
console.log(`Updated modular default navigation file: ${modularNavFile}`); fs.mkdirSync(CONFIG_USER_DIR, { recursive: true });
} }
}
// 创建基本导航配置
// 4. 最低优先级: 传统默认配置 const basicNav = [
if (!navigationUpdated && fs.existsSync(configFile)) { {
navigationUpdated = updateTraditionalConfig(configFile); name: "首页",
if (navigationUpdated) { icon: "fas fa-home",
console.log(`Updated legacy default config file: ${configFile} (lowest priority)`); id: "home",
active: true
},
{
name: "书签",
icon: "fas fa-bookmark",
id: "bookmarks",
active: false
}
];
// 写入用户导航文件
fs.writeFileSync(
modularUserNavFile,
yaml.dump(basicNav, { indent: 2, lineWidth: -1, quotingType: '"' }),
'utf8'
);
console.log(`Created basic navigation file: ${modularUserNavFile}`);
navigationUpdated = true;
} catch (error) {
console.error(`Error creating basic navigation file:`, error);
} }
} }
if (!navigationUpdated) { if (!navigationUpdated) {
console.log('Did not find any configuration file to update with bookmarks navigation'); console.log('Did not update any navigation configuration with bookmarks page');
} }
return navigationUpdated;
} }
// 更新单个导航配置文件(模块化版本) // 更新单个导航配置文件
function updateNavigationFile(filePath) { function updateNavigationFile(filePath) {
try { try {
const content = fs.readFileSync(filePath, 'utf8'); const content = fs.readFileSync(filePath, 'utf8');
@@ -304,55 +342,9 @@ function updateNavigationFile(filePath) {
} }
} }
// 更新传统配置文件(整体配置)
function updateTraditionalConfig(filePath) {
try {
const configContent = fs.readFileSync(filePath, 'utf8');
const config = yaml.load(configContent);
// 检查导航中是否已有书签页面
const hasBookmarksNav = config.navigation &&
Array.isArray(config.navigation) &&
config.navigation.some(nav => nav.id === 'bookmarks');
if (!hasBookmarksNav) {
// 确保navigation数组存在
if (!config.navigation) {
config.navigation = [];
}
// 添加书签页面到导航
config.navigation.push({
name: '书签',
icon: 'fas fa-bookmark',
id: 'bookmarks',
active: false
});
// 更新配置文件
const updatedYaml = yaml.dump(config, {
indent: 2,
lineWidth: -1,
quotingType: '"'
});
fs.writeFileSync(filePath, updatedYaml, 'utf8');
return true;
}
return false; // 无需更新
} catch (error) {
console.error(`Error updating config file ${filePath}:`, error);
return false;
}
}
// 主函数 // 主函数
async function main() { async function main() {
console.log('Starting bookmark processing...'); console.log('Starting bookmark processing...');
console.log(`Current working directory: ${process.cwd()}`);
console.log(`Legacy output file will be: ${OUTPUT_FILE} (absolute: ${path.resolve(OUTPUT_FILE)})`);
console.log(`Modular output file will be: ${MODULAR_OUTPUT_FILE} (absolute: ${path.resolve(MODULAR_OUTPUT_FILE)})`);
// 获取最新的书签文件 // 获取最新的书签文件
const bookmarkFile = getLatestBookmarkFile(); const bookmarkFile = getLatestBookmarkFile();
@@ -390,58 +382,37 @@ async function main() {
console.log(yaml.split('\n').slice(0, 5).join('\n') + '\n...'); console.log(yaml.split('\n').slice(0, 5).join('\n') + '\n...');
try { try {
// 确保传统目标目录存在 // 确保目标目录存在
const outputDir = path.dirname(OUTPUT_FILE); if (!fs.existsSync(CONFIG_USER_PAGES_DIR)) {
if (!fs.existsSync(outputDir) && outputDir !== '.') { console.log(`Creating output directory structure: ${CONFIG_USER_PAGES_DIR}`);
console.log(`Creating output directory: ${outputDir}`); fs.mkdirSync(CONFIG_USER_PAGES_DIR, { recursive: true });
fs.mkdirSync(outputDir, { recursive: true });
} }
// 确保模块化目标目录存在
const modularOutputDir = path.dirname(MODULAR_OUTPUT_FILE);
if (!fs.existsSync(modularOutputDir)) {
console.log(`Creating modular output directory structure: ${modularOutputDir}`);
fs.mkdirSync(modularOutputDir, { recursive: true });
}
// 保存YAML到传统位置
console.log(`Writing to legacy location: ${OUTPUT_FILE}`);
fs.writeFileSync(OUTPUT_FILE, yaml, 'utf8');
// 保存YAML到模块化位置 // 保存YAML到模块化位置
console.log(`Writing to modular location: ${MODULAR_OUTPUT_FILE}`); console.log(`Writing bookmarks configuration to: ${MODULAR_OUTPUT_FILE}`);
fs.writeFileSync(MODULAR_OUTPUT_FILE, yaml, 'utf8'); fs.writeFileSync(MODULAR_OUTPUT_FILE, yaml, 'utf8');
// 验证文件是否确实被创建 // 验证文件是否确实被创建
let success = false;
if (fs.existsSync(OUTPUT_FILE)) {
const stats = fs.statSync(OUTPUT_FILE);
console.log(`Successfully saved bookmarks configuration to ${OUTPUT_FILE}`);
console.log(`File size: ${stats.size} bytes`);
success = true;
} else {
console.error(`ERROR: Legacy file was not created: ${OUTPUT_FILE}`);
}
if (fs.existsSync(MODULAR_OUTPUT_FILE)) { if (fs.existsSync(MODULAR_OUTPUT_FILE)) {
const stats = fs.statSync(MODULAR_OUTPUT_FILE); const stats = fs.statSync(MODULAR_OUTPUT_FILE);
console.log(`Successfully saved bookmarks configuration to ${MODULAR_OUTPUT_FILE}`); console.log(`Successfully saved bookmarks configuration (${stats.size} bytes)`);
console.log(`File size: ${stats.size} bytes`);
success = true;
} else { } else {
console.error(`ERROR: Modular file was not created: ${MODULAR_OUTPUT_FILE}`); console.error(`ERROR: File was not created: ${MODULAR_OUTPUT_FILE}`);
}
if (!success) {
console.error('ERROR: No output files were created successfully');
process.exit(1); process.exit(1);
} }
// 更新导航 // 更新导航
updateConfigWithBookmarks(); updateNavigationWithBookmarks();
// 处理完成后删除原始HTML文件以防止重复处理
try {
fs.unlinkSync(bookmarkFile);
console.log(`Deleted processed HTML file: ${bookmarkFile}`);
} catch (deleteError) {
console.warn(`Warning: Could not delete processed HTML file: ${deleteError.message}`);
}
} catch (writeError) { } catch (writeError) {
console.error(`ERROR writing files:`, writeError); console.error(`ERROR writing file:`, writeError);
process.exit(1); process.exit(1);
} }
} catch (error) { } catch (error) {
@@ -450,8 +421,10 @@ async function main() {
} }
} }
// 执行主函数 // 启动处理
main().catch(error => { if (require.main === module) {
console.error('Unhandled error:', error); main().catch(err => {
process.exit(1); console.error('Unhandled error in bookmark processing:', err);
}); process.exit(1);
});
}

View File

@@ -131,24 +131,17 @@ function loadConfig() {
categories: [] categories: []
}; };
// 检查所有可能的配置来源是否存在 // 检查模块化配置来源是否存在
const hasUserModularConfig = fs.existsSync('config/user'); const hasUserModularConfig = fs.existsSync('config/user');
const hasUserLegacyConfig = fs.existsSync('config.user.yml');
const hasDefaultModularConfig = fs.existsSync('config/_default'); const hasDefaultModularConfig = fs.existsSync('config/_default');
const hasDefaultLegacyConfig = fs.existsSync('config.yml');
// 根据优先级顺序选择最高优先级的配置 // 根据优先级顺序选择最高优先级的配置
if (hasUserModularConfig) { if (hasUserModularConfig) {
// 1. 最高优先级: config/user/ 目录 // 1. 最高优先级: config/user/ 目录
console.log('Using modular user configuration from config/user/ (highest priority)'); console.log('Using modular user configuration from config/user/ (highest priority)');
config = loadModularConfig('config/user'); config = loadModularConfig('config/user');
} else if (hasUserLegacyConfig) {
// 2. 次高优先级: config.user.yml (传统用户配置)
console.log('Using legacy user configuration from config.user.yml');
const userConfigFile = fs.readFileSync('config.user.yml', 'utf8');
config = yaml.load(userConfigFile);
} else if (hasDefaultModularConfig) { } else if (hasDefaultModularConfig) {
// 3. 其次优先级: config/_default/ 目录 // 2. 其次优先级: config/_default/ 目录
console.log('Using modular default configuration from config/_default/'); console.log('Using modular default configuration from config/_default/');
// 从模块化默认配置加载 // 从模块化默认配置加载
@@ -174,11 +167,6 @@ function loadConfig() {
console.error(`Error loading home.yml: ${e.message}`); console.error(`Error loading home.yml: ${e.message}`);
} }
} }
} else if (hasDefaultLegacyConfig) {
// 4. 最低优先级: config.yml (传统默认配置)
console.log('Using legacy default config.yml');
const defaultConfigFile = fs.readFileSync('config.yml', 'utf8');
config = yaml.load(defaultConfigFile);
} else { } else {
console.log('No configuration found, using default empty config'); console.log('No configuration found, using default empty config');
} }
@@ -191,43 +179,29 @@ function loadConfig() {
config.social = config.social || []; config.social = config.social || [];
config.categories = config.categories || []; config.categories = config.categories || [];
// 处理书签文件(保持现有功能,但使用新逻辑) // 处理书签文件
try { try {
let bookmarksConfig = null; let bookmarksConfig = null;
let bookmarksSource = null; let bookmarksSource = null;
// 按照相同的优先级顺序处理书签配置 // 按照优先级顺序处理书签配置
// 1. 模块化用户书签配置 (最高优先级) // 1. 模块化用户书签配置 (最高优先级)
if (fs.existsSync('config/user/pages/bookmarks.yml')) { if (fs.existsSync('config/user/pages/bookmarks.yml')) {
const userBookmarksFile = fs.readFileSync('config/user/pages/bookmarks.yml', 'utf8'); const userBookmarksFile = fs.readFileSync('config/user/pages/bookmarks.yml', 'utf8');
bookmarksConfig = yaml.load(userBookmarksFile); bookmarksConfig = yaml.load(userBookmarksFile);
bookmarksSource = 'config/user/pages/bookmarks.yml'; bookmarksSource = 'config/user/pages/bookmarks.yml';
} }
// 2. 传统用户书签配置 // 2. 模块化默认书签配置
else if (fs.existsSync('bookmarks.user.yml')) {
const userBookmarksFile = fs.readFileSync('bookmarks.user.yml', 'utf8');
bookmarksConfig = yaml.load(userBookmarksFile);
bookmarksSource = 'bookmarks.user.yml';
}
// 3. 模块化默认书签配置
else if (fs.existsSync('config/_default/pages/bookmarks.yml')) { else if (fs.existsSync('config/_default/pages/bookmarks.yml')) {
const defaultBookmarksFile = fs.readFileSync('config/_default/pages/bookmarks.yml', 'utf8'); const defaultBookmarksFile = fs.readFileSync('config/_default/pages/bookmarks.yml', 'utf8');
bookmarksConfig = yaml.load(defaultBookmarksFile); bookmarksConfig = yaml.load(defaultBookmarksFile);
bookmarksSource = 'config/_default/pages/bookmarks.yml'; bookmarksSource = 'config/_default/pages/bookmarks.yml';
} }
// 4. 传统默认书签配置 (最低优先级)
else if (fs.existsSync('bookmarks.yml')) {
const bookmarksFile = fs.readFileSync('bookmarks.yml', 'utf8');
bookmarksConfig = yaml.load(bookmarksFile);
bookmarksSource = 'bookmarks.yml';
}
// 添加书签页面配置 // 添加书签页面配置
if (bookmarksConfig) { if (bookmarksConfig) {
config.bookmarks = bookmarksConfig; config.bookmarks = bookmarksConfig;
console.log(`Using bookmarks configuration from ${bookmarksSource}`); console.log(`Using bookmarks configuration from ${bookmarksSource}`);
// 移除自动添加书签页面到导航的逻辑
} }
} catch (e) { } catch (e) {
console.error('Error loading bookmarks configuration:', e); console.error('Error loading bookmarks configuration:', e);

178
src/migrate-config.js Normal file
View File

@@ -0,0 +1,178 @@
/**
* MeNav 配置迁移工具
* 将旧版双文件配置转换为新版模块化配置
*/
const fs = require('fs');
const path = require('path');
const yaml = require('js-yaml');
// 配置文件路径
const LEGACY_CONFIG_FILE = 'config.yml';
const LEGACY_USER_CONFIG_FILE = 'config.user.yml';
const LEGACY_BOOKMARKS_FILE = 'bookmarks.yml';
const LEGACY_USER_BOOKMARKS_FILE = 'bookmarks.user.yml';
// 模块化配置目录
const CONFIG_USER_DIR = 'config/user';
const CONFIG_USER_PAGES_DIR = path.join(CONFIG_USER_DIR, 'pages');
/**
* 迁移旧式配置文件到模块化格式
*/
function migrateConfiguration() {
console.log('\n======== MeNav 配置迁移工具 ========');
console.log('将旧式双文件配置转换为模块化配置\n');
// 检查是否存在旧式配置文件
const hasUserConfig = fs.existsSync(LEGACY_USER_CONFIG_FILE);
const hasDefaultConfig = fs.existsSync(LEGACY_CONFIG_FILE);
const hasUserBookmarks = fs.existsSync(LEGACY_USER_BOOKMARKS_FILE);
const hasDefaultBookmarks = fs.existsSync(LEGACY_BOOKMARKS_FILE);
if (!hasUserConfig && !hasDefaultConfig && !hasUserBookmarks && !hasDefaultBookmarks) {
console.log('未找到任何旧式配置文件,无需迁移。');
return;
}
// 确保目标目录存在
if (!fs.existsSync(CONFIG_USER_DIR)) {
fs.mkdirSync(CONFIG_USER_DIR, { recursive: true });
}
if (!fs.existsSync(CONFIG_USER_PAGES_DIR)) {
fs.mkdirSync(CONFIG_USER_PAGES_DIR, { recursive: true });
}
// 优先使用用户配置,如果不存在则使用默认配置
const configFile = hasUserConfig ? LEGACY_USER_CONFIG_FILE : hasDefaultConfig ? LEGACY_CONFIG_FILE : null;
// 迁移主配置文件
if (configFile) {
try {
console.log(`迁移配置文件: ${configFile}`);
const configContent = fs.readFileSync(configFile, 'utf8');
const config = yaml.load(configContent);
// 提取站点配置
if (config.site) {
const siteConfig = {
title: config.site.title || '',
description: config.site.description || '',
author: config.site.author || '',
favicon: config.site.favicon || 'favicon.ico'
};
// 添加字体配置
if (config.fonts) {
siteConfig.fonts = config.fonts;
}
// 添加个人资料配置
if (config.profile) {
siteConfig.profile = config.profile;
}
// 添加社交媒体配置
if (config.social && config.social.length > 0) {
siteConfig.social = config.social;
}
// 写入站点配置
const siteYaml = yaml.dump(siteConfig, { indent: 2, lineWidth: -1, quotingType: '"' });
fs.writeFileSync(
path.join(CONFIG_USER_DIR, 'site.yml'),
`# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${siteYaml}`,
'utf8'
);
console.log('✓ 已创建站点配置文件: site.yml');
}
// 提取导航配置
if (config.navigation && config.navigation.length > 0) {
const navigationYaml = yaml.dump(config.navigation, { indent: 2, lineWidth: -1, quotingType: '"' });
fs.writeFileSync(
path.join(CONFIG_USER_DIR, 'navigation.yml'),
`# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${navigationYaml}`,
'utf8'
);
console.log('✓ 已创建导航配置文件: navigation.yml');
}
// 提取所有页面配置
const pageIds = config.navigation ? config.navigation.map(nav => nav.id) : [];
pageIds.forEach(pageId => {
if (config[pageId]) {
const pageConfig = { ...config[pageId] };
// 特殊处理首页的categories
if (pageId === 'home' && !pageConfig.categories && config.categories) {
pageConfig.categories = config.categories;
}
const pageYaml = yaml.dump(pageConfig, { indent: 2, lineWidth: -1, quotingType: '"' });
fs.writeFileSync(
path.join(CONFIG_USER_PAGES_DIR, `${pageId}.yml`),
`# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${pageYaml}`,
'utf8'
);
console.log(`✓ 已创建页面配置文件: ${pageId}.yml`);
}
});
// 如果首页不在pageIds中但存在categories创建一个home.yml
if (!pageIds.includes('home') && config.categories) {
const homeConfig = {
title: '我的导航',
subtitle: '个人收藏网址',
categories: config.categories
};
const homeYaml = yaml.dump(homeConfig, { indent: 2, lineWidth: -1, quotingType: '"' });
fs.writeFileSync(
path.join(CONFIG_USER_PAGES_DIR, 'home.yml'),
`# 由migrate-config.js从${configFile}迁移\n# 生成于 ${new Date().toISOString()}\n\n${homeYaml}`,
'utf8'
);
console.log('✓ 已创建首页配置文件: home.yml');
}
} catch (error) {
console.error(`迁移配置文件${configFile}时出错:`, error);
}
}
// 迁移书签配置文件
const bookmarksFile = hasUserBookmarks ? LEGACY_USER_BOOKMARKS_FILE : hasDefaultBookmarks ? LEGACY_BOOKMARKS_FILE : null;
if (bookmarksFile) {
try {
console.log(`\n迁移书签配置文件: ${bookmarksFile}`);
// 直接复制书签配置文件
fs.copyFileSync(
bookmarksFile,
path.join(CONFIG_USER_PAGES_DIR, 'bookmarks.yml')
);
console.log('✓ 已创建书签配置文件: bookmarks.yml');
} catch (error) {
console.error(`迁移书签配置文件${bookmarksFile}时出错:`, error);
}
}
console.log('\n迁移完成');
console.log('您现在可以删除旧的配置文件:');
if (hasUserConfig) console.log(`- ${LEGACY_USER_CONFIG_FILE}`);
if (hasDefaultConfig) console.log(`- ${LEGACY_CONFIG_FILE}`);
if (hasUserBookmarks) console.log(`- ${LEGACY_USER_BOOKMARKS_FILE}`);
if (hasDefaultBookmarks) console.log(`- ${LEGACY_BOOKMARKS_FILE}`);
console.log('\n新的模块化配置文件位于');
console.log(`- ${CONFIG_USER_DIR}/`);
console.log(`- ${CONFIG_USER_PAGES_DIR}/`);
}
// 如果直接运行该脚本,则执行迁移
if (require.main === module) {
migrateConfiguration();
}
module.exports = { migrateConfiguration };