Skip to content

换新博客系统啦!

约 1265 字大约 4 分钟

vuepress

2025-08-30

用了很久的 hugo 作为自己的静态博客系统,在后续的拓展中发现愈发无法满足自己的需求。现在换成了基于 vue.js 的 vuepress 框架,使用了 plume 主题。这篇文章记录折腾的过程。

字体设置

字体是让博客整体外观好看的重要因素。中英文我选择了目前苹果系统的字体方案:苹方(中文)San Francisco(英文),代码使用 JetBrains Mono

我是从 webfontfree 下载的 woff2 格式字体。然后通过 @font-face 引入字体,并设置全局字体。vuepress 字体默认放在 .vuepress/public/fonts 下。

CSS @font-face设置
.vuepress/public/styles/index.css
/* 苹方-简 极细体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Ultralight.woff2') format('woff2');
  font-weight: 100;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 纤细体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Thin.woff2') format('woff2');
  font-weight: 200;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 细体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Light.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 常规体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 中黑体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 中粗体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Semibold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
/* 苹方-简 粗体 */
@font-face {
  font-family: 'PingFangSC';
  src: url('/fonts/PingFangSC/PingFangSC-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/JetBrainsMono/JetBrainsMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-007F;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/JetBrainsMono/JetBrainsMono-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-007F;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('/fonts/JetBrainsMono/JetBrainsMono-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-007F;
}

/* SFProText */
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Light.woff2') format('woff2');
  font-weight: 300;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-007F;
}
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Light-Italic.woff2') format('woff2');
  font-weight: 300;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-007F;
}
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-007F;
}
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Regular-Italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-007F;
}
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-007F;
}
@font-face {
  font-family: 'SFProText';
  src: url('/fonts/SFProText/SFProText-Bold-Italic.woff2') format('woff2');
  font-weight: 700;
  font-style: italic;
  font-display: swap;
  unicode-range: U+0000-007F;
}

然后设置各种全局字体:

.vuepress/public/styles/index.css
/* 设置全局字体 */
body {
  font-family: 'SFProText', 'PingFangSC', sans-serif;
}

/* 设置代码块字体 */
pre, code, kbd {
  font-family: 'JetBrains Mono', monospace;
}

最后在 client.ts 中引入该自定义CSS:

.vuepress/client.ts
import './public/styles/index.css'

评论设置

我使用的是 waline 作为评论字体,具体设置参考 Waline

默认的 Vercel 服务需要代理才能访问,可以绑定国内的域名来解决,需要在服务器运营商的域名中添加 CNAME 解析。我设置了博客的二级域名 comment.geekinney.com 作为评论系统。

.vuepress/config.ts
/**
 * 评论 comments
 * @see https://theme-plume.vuejs.press/guide/features/comments/
 */
comment: {
  provider: 'Waline',  // "Artalk" | "Giscus" | "Twikoo" | "Waline"
  comment: true,
  serverURL: 'comment.geekinney.com'
},

设置完成后便可以访问 https://comment.geekinney.com/ui 使用评论后台管理啦。

博客列表页问题

我当前使用的 plume 主题版本是 1.0.0-rc.161,会存在博客列表页在屏幕较小时会出现左右的滚动条,无法想博客内容页那样自适应各种不同尺寸的屏幕。

经过研究之后,可以在 .vuepress/public/styles/index.css 中设置下面的 CSS 解决:

.vp-blog-post-list {
  max-width: 100%;
}

我也给 vuepress-theme-plume 项目报了 PR

Github 持续集成

使用 github action 自动化部署和发布更新

.github/workflows/deploy.yml
name: Build and Sync VuePress Docs

on:
  push:
    branches: [ main ]
    paths:
      - 'docs/**'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 8

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

      # 缓存 pnpm store 和 node_modules
      - name: Cache pnpm modules
        uses: actions/cache@v4
        id: pnpm-cache
        with:
          path: |
            ~/.pnpm-store
            node_modules
          key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-

      # 缓存系统工具(避免重复安装 rsync)
      - name: Cache system tools
        uses: actions/cache@v4
        id: apt-cache
        with:
          path: /var/cache/apt/archives
          key: ${{ runner.os }}-apt-${{ hashFiles('.github/apt-packages') }}
          restore-keys: |
            ${{ runner.os }}-apt-
        
      - name: Install dependencies
        # 仅在 pnpm 缓存未命中时执行
        if: steps.pnpm-cache.outputs.cache-hit != 'true'
        run: pnpm install

      - name: Build VuePress docs
        run: pnpm run docs:build
        env:
          NODE_OPTIONS: --max_old_space_size=4096

      - name: Verify build output
        run: |
          echo "Build directory contents:"
          [ -d docs/.vuepress/dist ] || exit 1
          [ -f docs/.vuepress/dist/index.html ] || exit 1

      - name: Setup SSH
        id: setup-ssh
        run: |
          mkdir -p ~/.ssh
          chmod 700 ~/.ssh
          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          cat << EOF > ~/.ssh/config
          Host vuepress-deploy
            HostName ${{ secrets.REMOTE_HOST }}
            Port ${{ secrets.SSH_PORT || 22 }}
            User ${{ secrets.REMOTE_USER }}
            IdentityFile ~/.ssh/id_ed25519
            StrictHostKeyChecking no
            ConnectTimeout 30
          EOF
          chmod 600 ~/.ssh/config
          ssh -T vuepress-deploy || true

      # 更新包列表(使用缓存的索引文件)
      - name: Update package lists
        run: sudo apt-get update
        
      # 安装工具(自动使用缓存中已有的deb文件)
      - name: Install tools
        run: |
          # 从配置文件读取需要安装的包
          xargs -a .github/apt-packages sudo apt-get install -y --no-install-recommends

      - name: Sync to Remote Server
        run: |
          rsync -avz --checksum --progress --delete --stats \
          docs/.vuepress/dist/ vuepress-deploy:${{ secrets.REMOTE_PATH }}

      - name: Post-deployment cleanup
        run: |
          pnpm store prune
          rm -f ~/.ssh/id_ed25519