跳到主内容
Xinjie Cui

用 Astro 与 Cloudflare 搭建这个博客

约 2 分钟

这个站点的目标很朴素:写文章要顺手,读文章要快。围绕这两点,选型基本是被推导出来的。

静态优先

博客的内容在构建时就已确定,没有任何需要按请求计算的东西。所以输出纯静态 HTML,由 Cloudflare 的边缘节点直接返回,首字节时间只取决于最近的节点距离。

需要注意的是,静态并不等于没有交互。主题切换这类局部交互用一小段内联脚本就够了,不需要为此引入前端框架:

const root = document.documentElement;
root.dataset.theme = root.dataset.theme === 'dark' ? 'light' : 'dark';

Astro 默认不向浏览器发送组件运行时,页面里出现的 JS 是你自己写的那几行。

内容用 Content Layer 管

文章放在 src/content/posts/,通过 src/content.config.ts 里的 schema 校验 frontmatter:

const posts = defineCollection({
loader: glob({ base: './src/content/posts', pattern: '**/*.{md,mdx}' }),
schema: z.object({
title: z.string().max(120),
pubDate: z.coerce.date(),
draft: z.boolean().default(false),
}),
});

好处是写错字段名会在构建时报错,而不是等页面渲染出空白才发现。draft: true 的文章只在本地开发时可见。

Tailwind 4 的配置方式

Tailwind 4 把配置搬回了 CSS。设计 token 直接写在 @theme 里,深色模式则是覆盖同名变量,不需要给每个元素挂 dark: 变体:

@theme {
--color-ink: oklch(0.22 0.01 260);
}
:root[data-theme='dark'] {
--color-ink: oklch(0.93 0.008 260);
}

颜色用 oklch 而不是 hex,是因为它的亮度分量感知均匀,调深浅时不会顺带改变饱和度观感。

取舍

有几个决定值得说明:

  • 不上 SSR。 评论、搜索这类动态功能,可以等真的需要时再接第三方服务或加一个 Worker,没必要现在就把整站放进运行时。
  • 依赖锁精确版本。 package.json 里不带 ^,升级是显式动作,避免某次安装静默引入 breaking change。
  • CI 跑完整校验。 格式、lint、类型、构建四步,任一失败就不部署。

下一步

src/consts.ts 里的站点信息换成你自己的,删掉这篇示例,就可以开始写了。