← ALL NOTES
METHOD·2026.09·6 MIN READ
静态 Demo 站点的可扩展内容架构
dev-toolsprocess-design
问题

如果一个静态站点会持续新增原型,最早随手搭出来的结构很快就会碰到维护问题:每增加一个 demo,都要不要重新建页面、重新想部署方式、重新整理入口?

我之前做的是一个 3D 产品原型展示站点。最早只有一个完整原型,用来验证浏览器里的 3D 空间测量是否可行。后面随着问题逐渐拆细,开始出现很多更小、更专门的 demo,例如模型比例变化后的相机补偿、触屏 Gizmo、测量项复制后的移动方式。

这些 demo 不适合全部塞进同一个产品原型里,但如果每个都单独部署,链接、入口和维护方式又会越来越分散。

因此需要解决的不是"怎么再建一个页面",而是:怎样让站点可以持续增加 demo,同时保持一个统一入口、一套稳定约定和尽量低的部署成本。

这套架构方案是我和 Claude Code 一起讨论出来的。我负责把实际使用场景和约束说清楚:需要持续增加内容、可以单独分享、最好不用频繁改部署;Claude Code 提供技术选项和实现上的代价,最后再根据这些约束做取舍。

基础结构

最终保持纯静态站点,不给主站引入构建步骤,而是用一个清单文件驱动首页。

结构大致是:

Scanat-Demo/
├── index.html
├── demos.js
└── demos/
    ├── scale-transition/
    │   └── index.html
    ├── gizmo-touch/
    │   └── index.html
    └── ...

index.html 只负责读取 demos.js 并渲染项目卡片。每个 demo 都放在 demos/<slug>/ 下,保持自包含。

清单本身只是一个普通数组:

JAVASCRIPT
window.DEMOS = [
  {
    slug: 'scale-transition',
    title: '模型比例修改',
    description: '修改模型比例后,相机平滑拉近/拉远,让视觉尺寸保持不变',
    tag: '交互动效',
    accent: '#2f81f7',
    date: '2026-06',
  },
];

新增一个普通 demo,只需要两步:

  1. 新建 demos/<slug>/index.html;
  2. 在 demos.js 增加一条记录。

首页结构不需要继续改,也不需要为整个站点重新设计一套内容管理逻辑。

部署同样保持简单:整个仓库作为一个静态项目部署到 Vercel,所有 demo 都共享同一个项目和域名。这样新增内容不会同时增加新的部署对象。

为什么先不用框架

当时也讨论过要不要把整个站点改成 React 一类的框架项目。

最后没有这样做,原因不是排斥框架,而是主站本身没有这个需求。大部分 demo 都是自包含 HTML,加上通过 CDN 引入的 Three.js,本来没有构建过程。如果为了统一技术栈给整个站点增加框架,反而会让每一个简单 demo 都多出安装、构建和部署配置。

同样,首页也没有引入后台数据库。这个站点的内容数量不大、更新频率不高,一份 JS 清单已经足够把"新增卡片"从修改页面逻辑变成修改数据。

这两个决定背后的原则是一致的:只为当前已经存在的复杂度设计,不提前为可能出现的复杂度增加基础设施。

复杂 Demo 如何接入

后来确实出现了例外。

第五个 demo 使用 React Three Fiber 和 TypeScript,需要通过 Vite 构建。这时"所有 demo 都是原始静态文件"的假设不再成立,但主站本身并不需要因此重构。

处理方式是只给这个 demo 增加一层源码与构建产物的分离:

Scanat-Demo/
├── demos/<slug>/        ← 构建后的静态产物
└── sources/<slug>/      ← React / TypeScript 源码

开发过程仍然在 sources/<slug>/ 里进行;构建完成后,将静态产物放进对应的 demos/<slug>/。对于主站来说,它依然只是一个普通的静态 demo,demos.js 的注册方式也不变。

这样做之后,复杂度被限制在真正需要它的 demo 内部,而没有扩散到整个站点。

构建路径的一个坑

这套方式上线时遇到过一个具体问题。

Vite 默认生成的资源路径可能以站点根目录为基准,例如:

/assets/index-xxx.js

但这个 demo 实际位于:

/demos/<slug>/

如果直接把构建产物放进去,浏览器仍然会去根目录寻找 /assets/,最终导致线上资源 404。

解决方式是在构建时使用相对路径,例如设置:

JAVASCRIPT
base: './'

这样资源会相对于当前 demo 目录加载。

这个问题属于具体实现细节,但它也说明了一件事:把框架构建产物嵌进静态子目录时,必须确认产物是不是假设自己运行在站点根目录。

实现备注

普通 demo:直接把自包含文件放入 demos/<slug>/。

需要 Vite 构建的 demo:源码保留在 sources/<slug>/,构建时使用相对 base,再将 dist/ 内容放入对应的 demos/<slug>/。

主站继续以纯静态方式部署,新增框架 demo 不改变主站的 Vercel 配置。

为什么没有拆成多个部署项目

另一个可选方案,是让每个需要框架的 demo 都成为 Vercel 上的独立项目,或者进一步做成 monorepo 多应用结构。

这个方案技术上可行,但和最初要解决的问题冲突:我希望所有原型都有统一入口,并尽量避免每增加一个 demo 就增加一个新的部署对象。

因此最终没有因为单个 demo 更复杂,就改变整个站点的管理方式。复杂 demo 可以拥有自己的构建流程,但发布后的结果仍然进入同一套目录结构。

这里的关键不是要求所有 demo 使用相同技术,而是保持相同的发布接口。

经验总结
  1. 先稳定内容入口,再考虑统一技术栈。 一个持续增加 demo 的站点,统一访问方式和目录约定比所有项目都用同一种框架更重要。
  2. 简单内容用数据驱动即可。 当数量不大、更新频率不高时,一份清单文件已经可以把新增内容和页面逻辑分开。
  3. 复杂度尽量局部化。 某个 demo 需要框架,不代表整个站点都要升级成框架项目。
  4. 为不同实现保留同一个发布接口。 无论源码是什么技术,最终都以可独立访问的静态目录进入 demos/,主站就不需要关心内部实现。
  5. 子目录部署要检查资源路径。 构建产物如果默认假设运行在根目录,本地正常并不代表嵌入静态站点后仍然正常。
关于架构取舍

这套方案的技术细节主要依赖 Claude Code 提供的工程分析,我负责的是约束和取舍:哪些复杂度值得引入,哪些应该继续留在单个 demo 内,以及出现例外时要不要改变原来的站点结构。

后来看,这个架构真正有用的地方并不是"第一次选了纯静态",而是它给后续例外留出了空间。普通 demo 可以继续零构建,复杂 demo 可以单独使用框架,但最后都进入同一个发布结构。

对于这类个人原型站点,我更愿意保持一条稳定原则:允许内部实现不同,但不要让每一次技术变化都扩散成新的管理方式。

CONTINUE READING
从 Figma 组件属性到代码 Props2026.09Figma 设计系统的工程化落地2026.09