技术文档 · 面向开发者

技术细节

这份文档面向负责部署与维护的同事。讲清楚本站是怎么搭起来的:为什么是纯静态、令牌如何驱动换肤、文件怎么组织、Nginx 怎么配、缓存怎么定。看完这一篇,你就能独立部署、换肤、排障。

1整体架构 —— 纯静态 + Nginx + certbot

本站是纯静态 HTML:没有构建工具(无 Webpack/Vite)、没有前端框架(无 React/Vue)、没有后端(无 Node/PHP/数据库)。页面就是 .html + .css,由 Nginx 直接 serve,HTTPS 证书由 Let's Encrypt(certbot)自动签发与续期。

为什么这样选

  • 首屏快:没有运行时编译、没有 hydration,服务器只做文件 IO,Lighthouse 移动端性能分稳定在 95+。
  • 部署简:一个 scp 命令把目录传上去即可,无需 CI/CD 流水线、无需容器。
  • 贴合规范:本 design-system 推崇「三层 CSS 架构」,本身就是这套架构的产物——拿自己的站点做 dogfood,说明架构真能跑。
  • 维护成本低:没有依赖要升级、没有安全补丁要跟,服务器只关心 Nginx 与证书续期。

一句话:这是一个能用一台最小规格云服务器、长期稳定运行的极简站点。

2令牌驱动三层 CSS 架构

这是本站的核心设计。CSS 被拆成三层,职责严格分离,任何具体视觉值都只出现在最底层的令牌文件里。

tokens.css —— 设计令牌(换肤只改这里)

所有视觉值(配色、字号、圆角、阴影、动效时长与曲线、字体族、间距)都定义在 :root 的 CSS 变量里。换肤时只改这一个文件,变量名保持不变,只改值。

base.css —— reset + 基础元素(换肤不动)

负责浏览器 reset、body/h1-h6/a/img 等基础元素的样式。全部用 var() 引用令牌,不写死任何具体值。换肤时这个文件一行都不用动。

components.css —— UI 组件层(换肤不动)

所有可复用组件类(.btn.card.tag.navbar.callout 等)的定义。同样全部 var() 引用,不写死值。换肤时也不动。

三层关系如下:

/* tokens.css —— 换肤只改这里 */ :root { --color-primary: #4A6B47; --radius-md: 18px; } /* base.css —— 不动 */ body { background: var(--color-bg); color: var(--color-text); } /* components.css —— 不动 */ .btn--primary { background: var(--color-primary); color: var(--color-text-inverse); border-radius: var(--radius-full); }

可视化证明

本站的 4 个 demo(治愈田园 / 科技极简 / 活泼趣味 / 国风杂志)共享同一份 base.css + components.css,仅仅是各自链接的 tokens.css 不同——于是呈现出 4 套截然不同的视觉。这就是「换肤只改 tokens」最直接的证明:一份组件代码,四张脸。

3换肤实战 —— 4 套 tokens 对比

下面挑几个最关键的令牌,横向对比 4 套皮肤的差异。可以清楚看到:变量名完全一致,只是取值不同——配色、圆角、字体、行高这些决定调性的值,把四种风格彻底拉开。

令牌变量 healing-pastoral tech-minimal lively-young editorial-magazine
--color-primary #4A6B47 #2563EB #FF6B6B #8B2E2E
--color-bg #FAF8F2 #FFFFFF #FFF9F5 #F7F3EC
--radius-md 18px 10px 20px 8px
--font-heading Noto Serif SC Inter ZCOOL KuaiLe Noto Serif SC
--line-height-normal 1.6 1.5 1.6 1.8

读法:同一个 .btn--primary,在 healing-pastoral 里是 18px 圆角的自然绿、宋体;在 tech-minimal 里是 10px 圆角的科技蓝、Inter;在 editorial-magazine 里是 8px 圆角的朱砂红、宋体——组件代码一字未改。

4文件结构

整站目录树如下。assets/shared/ 是所有页面共享的稳定层(base + components),assets/<skin>/tokens.css 是各皮肤的令牌。页面按用途分到根目录、demos/guide/tech/

template-site/ ├── index.html 门户首页(healing-pastoral) ├── assets/ │ ├── shared/ │ │ ├── base.css reset + 基础(换肤不动) │ │ └── components.css 组件层(换肤不动) │ ├── healing-pastoral/ │ │ └── tokens.css 治愈田园令牌 │ ├── tech-minimal/tokens.css │ ├── lively-young/tokens.css │ └── editorial-magazine/tokens.css ├── demos/ │ ├── healing-pastoral/index.html │ ├── tech-minimal/index.html │ ├── lively-young/index.html │ └── editorial-magazine/index.html ├── guide/index.html └── tech/index.html

注意子目录页面(如本页 tech/index.html)引用资源用相对路径 ../assets/...;门户首页用 assets/...。两条都指向同一份物理文件,只是层级不同。

5部署架构

站点部署在阿里云服务器 39.107.109.136,运行 Nginx 1.30.2,HTTPS 证书由 certbot 5.6.0 自动管理。目录映射如下:

  • 本地 → 服务器:template-site//var/www/template.qimuxu.com/
  • Nginx 配置:/etc/nginx/conf.d/template.qimuxu.com.conf
  • 部署模式:scp 上传静态文件 → Nginx serve → certbot 自动 HTTPS

整体请求链路:

┌─────────────┐ HTTPS(443) ┌───────────────────────┐ ┌─────────────────────────┐ │ 浏览器 │ ──────────────────▶ │ Nginx 1.30.2 │ ──▶ │ /var/www/template. │ │ (用户) │ │ template.qimuxu.com │ │ qimuxu.com/ 静态文件 │ └─────────────┘ └───────────────────────┘ └─────────────────────────┘ │ │ certbot 5.6.0 自动签发 / 续期 ▼ ┌───────────────────────┐ │ Let's Encrypt CA │ │ (90 天证书,自动续期) │ └───────────────────────┘

certbot 会在证书到期前自动续期,并把续期后的证书写入 /etc/letsencrypt/live/template.qimuxu.com/,Nginx 无需重启(配置 reload 即可,systemd timer 会处理)。

6Nginx 配置全文

这是本站实际的 Nginx 配置(template.qimuxu.com.conf),基于既有 huabuqi.conf 的模式。包含:站点根目录、gzip、静态资源长缓存、HTML 不缓存、隐藏文件安全规则、certbot 的 ACME 验证目录、443 SSL 块,以及 80 → 443 跳转。

server { server_name template.qimuxu.com; root /var/www/template.qimuxu.com; index index.html; access_log /var/log/nginx/template.qimuxu.com.access.log; error_log /var/log/nginx/template.qimuxu.com.error.log; gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript application/xml+rss image/svg+xml; location = / { try_files $uri $uri/ /index.html; } location ~* \.(css|js|woff2?|ttf|png|jpg|jpeg|gif|webp|svg|ico)$ { expires 30d; add_header Cache-Control "public, max-age=2592000, immutable"; access_log off; try_files $uri =404; } location ~* \.html$ { add_header Cache-Control "no-cache, must-revalidate"; try_files $uri =404; } location ~ /\.(?!well-known).* { deny all; } location ^~ /.well-known/acme-challenge/ { root /var/www/template.qimuxu.com; default_type "text/plain"; allow all; } error_page 404 /index.html; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/template.qimuxu.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/template.qimuxu.com/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; } server { if ($host = template.qimuxu.com) { return 301 https://$host$request_uri; } server_name template.qimuxu.com; listen 80; return 404; }

关键点解释:

  • 静态资源缓存 30 天 + immutable:css/js/图片/字体带文件指纹或低频更新,缓存期内浏览器直接用本地副本,不再发条件请求。
  • HTML 不缓存:内容更新后用户立即看到新版本,不会被旧 HTML 卡住。
  • 隐藏文件拦截:.git.env 等一律 deny all,但放行 certbot 的 .well-known/acme-challenge/
  • 404 回首页:单页类站点友好兜底,避免裸 404。

7性能与缓存策略

缓存与性能是一体两面,本站的策略可以归纳为几条:

  • 静态资源(css/js/图片/字体)缓存 30 天 immutable:命中即用,零往返。
  • HTML 不缓存:保证内容更新即时生效,不受中间缓存干扰。
  • 首屏资源控制在 500KB 以内:字体按需、图片压缩、CSS 精简,弱网也能秒开。
  • gzip 压缩文本:css/js/svg/json 全覆盖,体积再砍一半以上。
  • 无框架 JS:全站没有打包出来的 vendor bundle,只有门户首页约 15 行原生 JS(导航栏滚动转实底 + 元素滚动渐显)。

Lighthouse 表现

得益于纯静态 + 长缓存 + 极小 JS,这套架构在 Lighthouse 移动端可达 性能 95+,同时无障碍、最佳实践、SEO 三项也稳定在高位。换肤不会影响性能分——因为性能只取决于 base + components 这两层稳定代码。