@tmg0 : home / blog / Smooth personal website - Astro + GitHub Pages
Smooth personal website - Astro + GitHub Pages

Repository: tmg0.github.io

I accidentally deleted a project that was previously using Nuxt theme with Alpine. This led me to consider trying out Astro, and unexpectedly, the entire process turned out to be incredibly smooth. The experience was further enhanced by the fact that GitHub Pages now supports Actions as a publishing source, which really made a significant difference.

ps: I’ve just started working on this project recently. If you’re interested, you might want to check out the commit history.

Astro

Astro is a modern frontend build framework designed to create high-performance web applications through Server-Side Rendering (SSR) and Partial Static Site Generation (SSG) techniques.

It enables developers to use multiple frontend frameworks within the same project while, by default, not sending any JavaScript to the client, ensuring lightning-fast access experiences.

Additionally, Astro supports deployment to GitHub Pages through actions, where pushing code triggers hooks to automatically deploy via continuous integration (CI). What’s more, it’s free! It’s truly worth giving it a try, don’t you think?

Init Project

实际上文档还蛮清楚的,但是我们还是来跟着走一遍叭:

npm create astro@latest

然后跟着提示选择自己期望的方式(这个 cli 工具真的很友好 但是不知道是咋实现的 以后有机会可以看一下源码

GitHub 上新建一个仓库,建议仓库名还是 .github.io 的格式(后面就不用配 base 了

在项目根目录下找到 astro.config.mjs 文件把 site 改为仓库的名字,它看起来应该是:

// astro.config.mjs
import { defineConfig } from 'astro/config'

// https://astro.build/config
export default defineConfig({
  site: 'https://tmg0.github.io'
})

到此为止,项目本身应该不用再做修改了,具体的语法还是去看一下文档叭(或者问问聪明的 ChatGPT

尝试一下 npm run dev 项目默认会运行在 4321 端口,看看效果

astro 同时也提供了 add 命令来添加一下常用的依赖体验还是非常不错的,颇有 nuxt modules 的感觉了

GitHub Actions

如果平时不接触 ci 的朋友可能了解的不多,实际上和 GitLab 也大差不差的。

作用就是定义一些仓库的钩子和要触发的操作,一般用来做一些 lint 和 test 的流程,但是现在 deploy 也可以直接从 actions 获取产物了,于是就可以实现 push 到指定分支自动发布的操作

废话不多说,直接一波 cv

# .github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  # Trigger the workflow every time you push to the `main` branch
  # Using a different branch name? Replace `main` with your branch’s name
  push:
    branches: [main]
  # Allows you to run this workflow manually from the Actions tab on GitHub.
  workflow_dispatch:

# Allow this job to clone the repo and create a page deployment
permissions:
  contents: read
  pages: write
  id-token: write

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout your repository using git
        uses: actions/checkout@v4
      - name: Install, build, and upload your site
        uses: withastro/action@v2
        # with:
        # path: . # The root location of your Astro project inside the repository. (optional)
        # node-version: 20 # The specific version of Node that should be used to build your site. Defaults to 20. (optional)
        # package-manager: pnpm@latest # The Node package manager that should be used to install dependencies and build your site. Automatically detected based on your lockfile. (optional)

  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

保存之后提交,在仓库 actions tab 栏下应该能看到已经开始执行 actions 的操作了

如果项目中使用了 pnpm / yarn 或者其他啥(我也不造啊)包管理工具的话,可能会导致构建失败并提示:

build
Error: No pnpm version is specified. Please specify it by one of the following ways: - in the GitHub Action config with the key "version" - in the package.json with the key "packageManager"

跟着提示来在 package.json 中添加一个字段申明:

{
  "packageManager": "pnpm@8.15.4"
}

再提交一次,应该就顺利的大功告成啦!

如果项目名没有做修改的话,直接在浏览器中输入 https://.github.io 应该就能看到辣。

Vue.js + Tailwindcss

基于astro对第三方ui框架的良好支持,我们可以很方便的享受响应式数据带来的便利,当然也可以很方便的通过 add 命令添加 vue 和 tailwind 的官方支持

npx astro add vue
npx astro add tailwind
pnpm add @vueuse/core

为了支持页面 theme 的更改我们同时也添加了 @vueuse/core 那么让我们愉快熟练的封装一个 vue component

<script setup lang="ts">
import { useDark } from '@vueuse/core'
import MoonSolid from './MoonSolid.vue'
import SunSolid from './SunSolid.vue'

const isDark = useDark()

function toggleDark(event?: MouseEvent) {
  isDark.value = !isDark.value
}
</script>

<template>
  <Component :is="isDark ? SunSolid : MoonSolid" fill="#6b7280" class="cursor-pointer" @click="toggleDark" />
</template>

这段代码作为前端开发的朋友应该问题不是很大叭,使用起来和普通的组件也并没有什么区别直接作为一个组件引入就好惹。

但是很快我们就会发现好像主题的切换并没有生效,开始怀疑可能是 vueuse 与 astro 不兼容?

谷歌一下就会发现有个 issue 提到因为是服务端渲染,组件本身作为 html 被发送到浏览器内容就已经确定了,所以我们需要指定这个 vue component 只在客户端渲染:

<ThemeSwitch client:only />

很好,现在把 isDark 输出到页面能看到响应式数据已经变了,但是并没有触发 tailwind 切换到 dark theme,已经开始头大了

让我们翻翻 tailwind 文档 会发现他是通过查询 prefers-color-scheme 的 css 属性来判断当前主题,如果我们需要手动切换的话就需要:

// tailwind.config.mjs

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: 'selector',
  // ...
}

再试一下~完美!

最后

如果有一些自定义域名的需求的话,可以参考部署文档

文档中还有很多其他平台的部署方式,尝试了 vercel 也是非常方便(但是没有选到想要的 domain 所以还是换回 GitHub Pages 了

祝大家一切顺利!

欢迎来我主页看看有啥感兴趣的嗷 ⇒ tmg0