背景 链接到标题
原有站点基于传统 CMS,内容管理成本高,改动一次需要走完整的发布流程。业务方希望站点更轻、更稳、更容易维护,最终决定重构为纯静态站点。
技术选型 链接到标题
最终选用 Astro 7 + Tailwind 3,output: "static",输出纯静态文件,零客户端 JS,部署到对象存储 + CDN。
选择理由:
- Astro 的 Islands 架构默认不输出 JS,适合以内容为主的官网
- Tailwind 3 的 JIT 模式可以快速迭代 UI,无需手写大量 CSS
- 静态产物可直接托管到任何对象存储,成本低、访问快
目录结构与路由 链接到标题
src/
pages/
index.astro # 首页
about.astro # 关于
contact.astro # 联系
services/
index.astro # 服务列表
[slug].astro # 服务详情(动态路由)
404.astro # 自定义 404
layouts/
BaseLayout.astro # 全局布局
components/
SiteNav.astro # 导航
Hero.astro # 首屏
ServiceCard.astro # 服务卡片
SiteFooter.astro # 页脚
data/
services.ts # 服务数据
styles/
global.css # 全局样式 + 自定义工具类
关键设计:服务数据集中存放在 services.ts,[slug].astro 通过 getStaticPaths 自动生成静态页面,新增服务只需改数据文件,无需新增路由。
核心设计决策 链接到标题
设计系统:浅色简约风,单一品牌渐变(violet → cyan),配合大留白、细描边、微投影,整体参考 Linear / Stripe 官网的克制精致感。
字体:Inter(英文/数字)+ 系统中文栈,通过 Google Fonts 引入。
自定义工具类:定义在 global.css 中,通过 BaseLayout.astro 全局引入:
.text-gradient:紫青渐变文字.bg-grid:淡色网格背景.card-hover:hover 上浮 + 紫色辉光投影
服务数据驱动 链接到标题
services.ts 定义服务数组,每项包含 slug、title、icon、description、fullDescription、highlights 六个字段。
服务列表页和详情页都从这个数据源渲染。新增服务时只需在 services.ts 添加条目,并在 public/icons/ 下添加对应 SVG 图标,路由自动生成。
部署流程 链接到标题
构建产物在 dist/,一键部署脚本完成三个步骤:
npm run build生成静态文件- 同步到对象存储,根
index.html单独设置不缓存头,其余资源长期缓存 - 触发 CDN 目录刷新,让最新版本生效
站点完全静态,没有数据库,没有运行时依赖,回滚只需重新上传产物。
踩坑记录 链接到标题
子目录首页未开启导致页面丢失
对象存储默认不处理目录索引。访问 /services 时返回 NoSuchKey XML,需要手动开启「子目录首页」并填入 index.html。
oss sync 的 exclude 陷阱
--exclude "index.html" 按文件名匹配,会排除所有子目录下的 index.html,导致 /services、/about 等页面全部丢失。改用全量同步 + 单独处理根 index.html 的缓存头。
二进制文件被静默跳过
对象存储的同步工具对二进制文件若大小恰好与原文件相同会跳过,修改 logo 或 favicon 后需要加 --force 强制覆盖。
404 页需要单独配置
404.html 上传后,还需在对象存储控制台的「静态网站托管」中手动填入默认 404 页,否则不会自动调用。
总结 链接到标题
Astro 适合以内容为主的官网:零客户端 JS、组件化开发体验、纯静态产物。配合 Tailwind 的 utility-first 方式,UI 迭代速度快,维护成本低。部署到对象存储 + CDN 的方案简单可靠,适合不需要后端的展示型站点。