博客的构建流水线是怎么跑的
文章写完之后, 总不能手动一条条部署. 自动化的目的很简单: push 完代码就什么都不用管了.
本质上就两件事: 把 Markdown 变成静态文件扔到网上去, 顺便把构建流程自动化.
Gulp 任务
整个构建就两个 Gulp 任务, 串行跑:
gulp.task("default", gulp.series('build', 'generate-service-worker'));
build
gulp.task('build', () => gulp.src('./').pipe(shell(['hugo --buildFuture --minify'])));
一行代码. 调用 Hugo 构建, --buildFuture 允许发布未来日期的内容, --minify 在构建时做 HTML/CSS/JS 压缩.
为什么用 gulp-shell 而不是直接调用 Hugo? 因为后续需要在构建完成后做一些处理, Gulp 作为编排工具把任务串起来比较方便. 如果用 npm script 串命令也可以, 但 Gulp 的 task 定义更清晰, 错误处理也更直接.
generate-service-worker
gulp.task('generate-service-worker', () => {
return workbox.generateSW({
globDirectory: './public',
globPatterns: ['**/*.{woff2,woff,js,css,png.jpg}'],
globIgnores: ['sw.js'],
swDest: `./public/sw.js`,
clientsClaim: true,
skipWaiting: true,
runtimeCaching: [
{ urlPattern: /.*\.js/, handler: 'NetworkFirst' },
{ urlPattern: /.*\.css/, handler: 'StaleWhileRevalidate' },
{ urlPattern: /.*\.(?:png|jpg|jpeg|svg|gif)/,
handler: 'CacheFirst',
options: { cacheName: 'images', expiration: { maxEntries: 50 } } },
{ urlPattern: /.*\.html/, handler: 'NetworkFirst' }
]
})
.then(() => console.info('Service Worker 生成完成'))
.catch(error => console.warn('Service Worker 生成失败: ' + error));
});
这个任务用 Workbox 自动生成 SW, 具体原理和缓存策略在 PWA 与 Service Worker 那篇里讲了.
CI/CD
用 GitHub Actions 自动构建部署. 配置文件 .github/workflows/deploy.yml:
name: Deploy to Cloudflare Pages
on:
push:
branches: [master]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: peaceiris/actions-hugo@v3
with:
hugo-version: "0.164.0"
extended: true
- uses: actions/setup-node@v4
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Patch theme for Hugo compatibility
run: bash scripts/patch-theme.sh
- name: Build
run: npm run build
- name: Deploy to Cloudflare Pages
run: npx wrangler pages deploy public --project-name=time-friend
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
触发条件: push 到 master 或手动触发.
流程:
- checkout 代码
- 装 Hugo extended 版本 (需要 extended 来处理 SCSS)
- 装 Node 24 并缓存 node_modules
npm ci安装依赖 (比 npm install 快, 但要求 lock 文件必须存在且跟 package.json 一致. 如果本地忘了 commit lock 文件, CI 会直接挂掉. 遇到过.)- 执行 theme patch 脚本 (修复旧主题在新 Hugo 下的兼容问题)
npm run build触发 Gulp 构建- 用 wrangler 部署到 Cloudflare Pages
CLOUDFLARE_API_TOKEN 和 CLOUDFLARE_ACCOUNT_ID 存在 GitHub Secrets 里, 不在代码中暴露.
性能考虑
整个构建过程从 push 到部署上线, 大概两分钟. 其中构建本身十秒以内, 主要时间花在依赖安装和部署上.
Service Worker 的缓存策略直接影响了页面加载性能. 首屏加载依赖 NetworkFirst 策略的资源需要等待网络, 但由于静态站点的 HTML 体积很小 (通常 5-10KB), 网络请求开销不大. 后续页面导航时, 大部分资源已经在缓存中, 体验接近原生应用.
workbox.generateSW 生成的 SW 文件大约 5KB, 对整体加载体积的影响可以忽略.