Skip to content
Go back

博客折腾小记,迁移 Astro

 at  Updated: 12 min read
Edit

起因

今天花了几乎一整天,把博客框架从 Hexo 迁移到了 Astro。我的博客最开始是在 2019 搭建的,哪个时候 Hexo 还是比较流行的静态博客生成框架,NexT 主题也是 Hexo 框架中比较流行的主题。在那一年,可以看到很多使用 NexT 主题的博客,如今看到的就似乎比较少了。经过六年的前端技术发展,Hexo 多少还是显得有点落后了,并不是基于当前流行的 React、Tailwind CSS、TypeScript 这样的主流前端框架,定制一些页面对我这个前端新手着实存在不小的困难。

说起原来博客的页面,本身主题是基于 NexT。为了稍显一些个人博客的不同之处,当时硬编码 CSS,使用 Chrome Dev Console,参考 Twitter 的暗色主题,设计了一套暗色的 color scheme。但是如今再想让我去修改这些配置,完全就有心无力了。而且博客只有一种主题,虽然 NexT 支持配置亮色和暗色主题,但是并不支持动态切换,我又完全没有能力去修改博客框架,让其支持主题切换。

恰巧又有很多博客主,都有迁移到 Astro 的博文。大致浏览了 Astro 的文档,基本满足我的需求。Astro 本身也是基于主流的前端技术,我也在这段时间里,粗糙地学了一遍前端的主流技术,这次就选择了 Astro 作为新的博客框架,还是希望能够使用长久一些,不再折腾博客框架,安安心心写博客文章。

Astro Paper

选定了 Astro 作为博客框架后,我选择的博客主题是 AstroPaper。吸引我的主要是主题样式和使用的技术栈。AstroPaper 主题足够简洁,基本没有影响阅读的元素。

主要戳中我的是下面这些点:

我使用的是 pnpm 包管理器,也可以参考官网文档,使用其他包管理器,使用下面的命令就可以创建一个 AstroPaper 主题的博客:

pnpm dlx create-astro --template satnaing/astro-paper

更新:

过了一段时间之后,我发现上面这条命令也是 clone 的主题的官方仓库,考虑到后续同步上游的更新,我做了修改。 更换成了 fork 原仓库,在 blog 分支修改配置我的个人博客。

博客基础配置

网站的相关配置,就直接配置在 config.ts 就可以了。参考原有 Hexo 配置,手动配置新的配置文件。

如果不需要迁移博客,那么简单配置下,其实就已经可以使用,我则需要把历史的 Hexo 博客的重要配置迁移到 Astro Paper 上,以下是一些记录。

迁移

博客文章迁移

Astro 的博客文章虽然和 Hexo 一样,都是 Markdown 语法,但是一些元数据方面的设置不太一样。

于是最开始的任务就是编写脚本,将历史数据转换内容到新的数据格式。最近也一直在尝试 AI 编程,Deepseek 的服务最近又一直不太稳定,没办法使用 vscode + deepseek api + cline 编程,就尝试了字节的 Trae,毕竟可以免费使用 Claude-3.5-Sonnet,效果非常 nice。脚本放在了这里,以及使用说明

LaTeX 数学公式支持

基本参考官方文档操作, Adding LaTeX Equations in AstroPaper blog posts | AstroPaper

  1. Install the necessary remark and rehype plugins
pnpm install rehype-katex remark-math katex
  1. 编辑 astro.config.ts
// other imports
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";

export default defineConfig({
  // other configs
  markdown: {
    remarkPlugins: [
      remarkMath,
      remarkToc,
      [
        remarkCollapse,
        {
          test: "Table of contents",
        },
      ],
    ],
    rehypePlugins: [rehypeKatex],
    // other markdown configs
  },
  // other configs
});
  1. 编辑 src/layouts/Layout.astro
---
import { LOCALE, SITE } from "@config";

// astro code
---

<!doctype html>
<!-- others... -->
<script is:inline src="/toggle-theme.js"></script>
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
/>

<body>
  <slot />
</body>

不过行间公式在暗色模式下存在渲染错误,在 issue 区看到其他人也存在同样的问题,但是没能解决。我现在使用数据公式比较少,就暂时搁置不处理了。

更新:尝试一翻之后,我找到了解决方案,放在了 issue 区

历史博客文章路径兼容

原本 hexo 的路径引用是 blog.guanglai.me/post-name,在 AstroPaper 主题中的文章路径是 blog.guanglai.me/posts/post-name,于是想到了下面两种解决方案。

第一种方案

修改 astro 的文章路径,保持一致

  1. posts 下的文件放到上级目录 pages 下,删除 index.astro
  2. 修改其他页面的路径引用路由,/posts/${slug}/,删除 /posts
    1. Posts.astro
    2. TagPosts.astro

第二种方案

使用 Astro 提供的重定向功能,将原来的博客地址,重定向到新的博客地址。这是 Astro 的路由文档 Routing | Docs,修改 astro.config.ts 就可以定义静态路由重定向。于是同样编写了脚本,将原有的 /post-name 全部重定向到 /posts/post-name,脚本放在这里

// astro.config.ts
import { defineConfig } from 'astro/config';

export default defineConfig({
  redirects: {
    '/old-page': '/new-page',
    '/blog': 'https://example.com/blog'
  }
});

文章目录

当时看到了这篇文章 再见 Hexo,你好 Astro! | 4Ark, 参考博主的配置,实现了大屏幕下的目录展示。具体修改直接参考博客的 commit 即可。

sitemap、rotbots.txt 和 RSS

AstroPaper 会自动生成需要的文件,但是使用 pnpm dev 开发阶段不会生成下面这些文件,pnpm build 构建最终产物才会生成。本地可以使用 pnpm preview 在构建好后预览。

GitHub Page 自定义域名

CNAME 文件配置在 public 目录下,用于 GitHub 自定义域名。

文件内容

blog.guanglai.me

OG 图片

AstroPaper 支持生成 OG 图片,但是原有的主题字体默认只支持 Latin 字符,对于非 Latin 字符的博客,需要自定义加载相关字体。

我加载了以下字体,后续看是否需要减少一些:

// file: loadGoogleFont.ts

async function loadGoogleFonts(
  text: string
): Promise<
  Array<{ name: string; data: ArrayBuffer; weight: number; style: string }>
> {
  const fontsConfig = [
    {
      name: "Noto Sans CJK JP", // 日文字体
      font: "Noto+Sans+JP", // Google Fonts 中的名称
      weight: 400,
      style: "normal",
    },
    {
      name: "Noto Sans CJK JP",
      font: "Noto+Sans+JP:wght@700", // 加粗版本
      weight: 700,
      style: "normal",
    },
    {
      name: "Noto Sans CJK SC", // 简体中文字体
      font: "Noto+Sans+SC", // Google Fonts 中的名称
      weight: 400,
      style: "normal",
    },
    {
      name: "Noto Sans CJK SC",
      font: "Noto+Sans+SC:wght@700", // 加粗版本
      weight: 700,
      style: "normal",
    },
    {
      name: "Noto Sans CJK TC", // 繁体中文字体
      font: "Noto+Sans+TC", // Google Fonts 中的名称
      weight: 400,
      style: "normal",
    },
    {
      name: "Noto Sans CJK TC",
      font: "Noto+Sans+TC:wght@700", // 加粗版本
      weight: 700,
      style: "normal",
    },
  ];
  // other codes
}

facicon 图标

原有在 Hexo 上使用的图标格式是 pngico,并且内容是动漫截图,其实也没有特别的含义,只是我曾经使用过的头像之一。于是这次就一起换了图标。

部署到 GitHub Page

Astro 官方有部署到 GitHub Page 的指导,提供了但是官方文件是源文件和网站在同一个 GitHub 仓库,我则是把源文件仓库设为私有,需要部署到目标仓库。经过了一翻调研,也就不使用官方部署指南提供的 GitHub Action 配置了。

.github/workflows 下,新建文件 deploy.yml,文件内容如下:

name: GitHub Pages

on:
  push:
    branches:
      - main
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      contents: write
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          run_install: false

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - name: Install dependencies
        run: pnpm install

      - name: Build
        run: pnpm build

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v4
        with:
          deploy_key: ${{ secrets.TARGET_REPO_DEPLOY_KEY }} # targert repository deploy key secret
          external_repository: knothhe/knothhe.github.io
          publish_dir: ./dist
          publish_branch: master  # default: gh-pages

使用 peaceiris/actions-gh-pages@v4 的 deploy key 的方式推送的目标仓库,所以需要在目标仓库和源仓库配置 DEPLOY_KEY 的公钥和私钥。

步骤参考:

  1. 本地生成 ssh 公钥和私钥,不带 passphare。
ssh-keygen -C "github@action"
  1. 目标仓库配置公钥
    1. 依次点击 Settings > Deploy keys > Add deplay key
    2. 配置设置
      配置设置
    3. 生成的公钥,即带有 .pub 后缀的文件的内容复制到文本框中
  2. 源仓库配置私钥
    1. 依次点击 Settings > Secrets and variables > Actions > New repository secret
    2. 配置设置
      配置设置
    3. 生成的公钥,即不带有 .pub 后缀的文件的内容复制到文本框中

Google Site Verification

官方推荐是使用 .env 配置,但是 .gitignore 文件里,忽略了 .env 文件,所以考虑本地生成时,可以配置 .env 文件,使用 GitHub 时,将内容配置到 GitHub 仓库中。

# in your environment variable file (.env)
PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value

采用密钥配合 GitHub Action 方式配置

      - name: Create .env file
        run: |
          echo "PUBLIC_GOOGLE_SITE_VERIFICATION=${{ secrets.GOOGLE_SITE_VERIFICATION_SECRET }}" >> .env

评论

采用 giscus,参考 AstroPaper 官方集成 Giscus 的文章

后记

本次折腾基本就是做了上面这些步骤,花费了几乎一天的时间。


Edit
文章标题:博客折腾小记,迁移 Astro
文章链接: https://blog.guanglai.me/posts/blog-migrate-to-astro/

商业转载请联系站长获得授权,非商业转载请注明本文出处及文章链接。您可以自由地在任何媒体以任何形式复制和分发作品,也可以修改和创作,但分发衍生作品时必须采用相同的许可协议。

本文采用 CC BY-NC-SA 4.0 进行许可。


Previous Post
Markdown Style Guide
Next Post
已读乱码 009