TIPNodeseek 上看到有人说 Hexo 过时了,现在用 astro 更好。我一想,反正我写作是 markdown 啊,迁移成本应该远小于 ghost - wordpress 之类的,只要换个编译期就行了,于是开始折腾
NOTEObsidian Git - Submodule - Github Repo - Github Action - Github Public Repo - Cloudflare Page 路径不变,Github Repo 换用 Astro Fuwari 的 fork
核心迁移策略:原地替换,内容至上
最稳妥的迁移方法是原地替换,即在原有的 Git 目录下,清理 Hexo 引擎,注入 Astro 引擎,但必须确保文章源码 (Markdown) 绝对安全。
迁移前的目录结构 (Hexo npm 模式)
GitBlog/├── .git/ <-- 必须保留,连接远程仓库├── node_modules/ <-- 需清理├── source/ <-- 核心内容,需备份│ └── _posts/ <-- 所有文章 (.md)├── themes/ <-- 需清理├── _config.yml <-- 需清理└── package.json <-- 需清理实战演练:五步完成“换脑”手术
Step 1:备份文章源码 (资产保全)
在进行任何删除操作前,先把文章拷贝到安全的地方:
# 假设你当前在父目录mkdir -p ./temp_posts && cp -r ./GitBlog/source/_posts/* ./temp_posts/Step 2:清理旧引擎 (暴力拆解)
进入项目目录,除了 .git 文件夹,清理其余所有 Hexo 相关文件:
cd ~/obsidian_vault/GitBlog# 慎重:确保你已经完成了上一步的备份!rm -rf source themes scaffolds _config.yml _config.butterfly.yml package.json package-lock.json node_modules db.jsonStep 3:初始化 Astro (旁路注入)
由于 Astro 脚本默认不接受非空目录,我们需要先在一个临时文件夹里初始化,再搬运回来:
# 1. 回到父目录,在临时文件夹里初始化 Astro Blog 模板cd ~/obsidian_vaultnpm create astro@latest ./astro-temp -- --template blog --no-git --no-install
# 2. 将临时文件夹里的所有文件(包含隐藏文件)拷贝回 GitBlogcp -r ./astro-temp/.* ./GitBlog/cp -rn ./astro-temp/ ./GitBlog/
# 3. 删除临时文件夹rm -rf ./astro-tempStep 4:适配 Front Matter & 搬回文章
Astro 默认的文章路径在 src/content/blog/。
- 搬回文章:
Terminal window mkdir -p GitBlog/src/content/blog/mv ../temp_posts/* GitBlog/src/content/blog/ - 适配 Config (zod schema):
Hexo 的
date格式和自定义字段 (如tags,categories,updated,abbrlink) 会让 Astro 报错。你需要修改src/content/config.ts来兼容它们:const blog = defineCollection({type: 'content',schema: z.object({title: z.string(),description: z.string().optional(),// 关键:将 Hexo 的日期字符串强制转换为 Date 对象pubDate: z.coerce.date(),updatedDate: z.coerce.date().optional(),heroImage: z.string().optional(),// 添加 Hexo 自定义字段tags: z.array(z.string()).optional(),categories: z.array(z.string()).optional(),abbrlink: z.string().optional(),}),});
Step 5:本地预览与验证
cd GitBlognpm installnpm run dev访问 http://localhost:4321/,你会看到一个全新的、速度极快的 Astro 博客,而且你的旧文章都在!
云端 CI/CD 换脑:GitHub Actions 适配
由于引擎更换,原本的 deploy.yml 需要彻底重写。Astro 的编译产物在 dist/,我们需要用 npm run build 替换 hexo g。
全新的 .github/workflows/deploy.yml:
name: Astro Auto Deploy
on: push: branches: - main
env: FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs: build: runs-on: ubuntu-latest steps: - name: Checkout source uses: actions/checkout@v4 with: submodules: true
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '24' cache: 'npm'
- name: Install & Build run: | npm install npm run build
- name: Configure SSH env: SSH_ID_RSA: ${{ secrets.HEXO_DEPLOY_PRI }} run: | mkdir -p ~/.ssh/ echo "$SSH_ID_RSA" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan github.com >> ~/.ssh/known_hosts
- name: Deploy to Private Static Repo run: | # 进入 Astro 的构建产物目录 cd dist # 初始化临时 Git 环境并推送到静态私有仓库 git init git config --global user.name "your_username" git config --global user.email "your_email@example.com" git remote add origin git@github.com:yourname/yourname.github.io.git git checkout -b main git add . git commit -m "Rendered by Astro" # 强制覆盖,确保结构纯净 git push -f origin main注意:Cloudflare Pages 无需做任何修改。它只管监听静态仓库
yourname.github.io,无论是 Hexo 推送的public还是 Astro 推送的dist,对于 Cloudflare 来说,它只看.html文件。
扫尾工作:仓库改名与 Obsidian 优化
为了更清晰地表达,我将远程源码仓库改名为 static-blog-source。
5.1 本地与 Submodule 同步
# 1. 更新本地 Git 远程地址cd GitBloggit remote set-url origin git@github.com:yourname/static-blog-source.git
# 2. 回到父目录 (Obsidian 主库),同步子模块路径cd ..# 慎重:确保你已经在 GitHub 网页端完成了改名操作git submodule sync5.2 Obsidian 侧边栏正则过滤 (File Explorer++)
由于 Astro 的目录结构复杂,我们需要更新正则过滤,让侧边栏只显示文章目录: Hide Filter:
^GitBlog/(?!(src/|src$)).*|^GitBlog/src/(?!(content/|content$)).*|^GitBlog/src/content/(?!(blog/|blog$)).*避坑
- Hexo 迁移过来 front-matter 内要用 category 而不是 categories!
- 还有发布日期等,最好全部从模板中复制到 templater