# 第2章 基础工作流:设计端产出 JSON、构建工具选型、云存储与CDN架构概览
## 2.1 设计端 → JSON 的标准化产出
Material 3 设计系统的核心是将设计决策(颜色、字体、间距、圆角、阴影等)固化为**可编程的设计令牌**。设计端(Figma 插件、 Studio、Specify、Supernova)负责将离散的设计属性转换为结构化的 JSON,作为整个工作流的唯一输入源。
**标准 JSON 结构示例(简化):**
{
"$schema": "https://design-tokens.example.com/schema/v2",
"color": {
"primary": { "$value": "#6750A4", "$type": "color" },
"on-primary": { "$value": "#FFFFFF", "$type": "color" },
"primary-container": { "$value": "#EADDFF", "$type": "color" },
"on-primary-container": { "$value": "#21005D", "$type": "color" },
"secondary": { "$value": "#625B71", "$type": "color" },
"tertiary": { "$value": "#7D5260", "$type": "color" },
"error": { "$value": "#B3261E", "$type": "color" },
"background": { "$value": "#FFFBFE", "$type": "color" },
"surface": { "$value": "#FFFBFE", "$type": "color" }
},
"font": {
"body-large": {
"$value": {
"fontFamily": "Roboto, sans-serif",
"fontWeight": "400",
"fontSize": "16px",
"lineHeight": "24px",
"letterSpacing": "0.5px"
},
"$type": "typography"
}
},
"spacing": {
"xs": { "$value": 4, "$type": "dimension" },
"sm": { "$value": 8, "$type": "dimension" },
"md": { "$value": 16, "$type": "dimension" },
"lg": { "$value": 24, "$type": "dimension" },
"xl": { "$value": 32, "$type": "dimension" }
}
}
**设计端产出检查清单:**
| 检查项 | 要求 | 自动化验证方式 |
|---------|------|----------------|
| Schema 版本 | 必须声明 `$schema` URL | JSON Schema 校验 |
| 数值类型 | `$type` 必须枚举合法值 | type-check 预检 |
| 颜色格式 | 统一使用 `#RRGGBB` 或 `#AARRGGBB` | 正则/颜色转换工具 |
| 命名规范 | 遵循 Material 3 命名拓扑 | eslint-plugin-design-tokens |
| 空值/缺失 | 禁止遗漏必需引用(如 on-primary) | 依赖图遍历检查 |
> **提示:** 设计端产出的 JSON 文件建议统一命名为 `tokens.json` 或 `design-tokens.json`,并放入项目仓库根目录的 `design/` 文件夹。后续构建工具会以此路径为入口。
## 2.2 构建工具选型对比
从 JSON 到平台主题 CSS(Web)、Compose(Android)、SwiftUI(iOS)的转换,需要依赖配置驱动型构建工具。当前主流选型为 **Style Dictionary** 和 **Theo**,二者同为 Design 转译引擎,但生态与扩展性差异明显。
| 对比维度 | Style Dictionary | Theo |
|----------|------------------|------|
| 维护状态 | 活跃(Amazon 开源,社区驱动)| 停止新功能开发 |
| 输出格式 | CSS、SCSS、Less、JS、JSON、Swift、Kotlin | CSS、SCSS、JSON、JS |
| 自定义转换 | Transform + Format + Action 三层扩展 | 仅支持 Transform |
| 平台适配 | 内建 Android/iOS/Web 模板 | 主要面向 Web |
| 文件拆分 | 支持多 JSON 源文件合并 | 仅单入口文件 |
| CLI / API | CLI 全局命令 + Node.js API | Gulp 插件为主 |
| 漏洞修复 | 活跃,持续更新 | 已停止补丁 |
**推荐选型策略:**
- 多平台并发(Web + Android + iOS):选择 **Style Dictionary**,利用其内建目标模板。
- 纯 Web 主题快速上线:可选用 **Theo**,但需注意版本锁定与安全补丁。
**Style Dictionary 基础配置示例(config.json):**
{
"source": ["design/tokens.json"],
"platforms": {
"css": {
"transformGroup": "css",
"buildPath": "build/web/",
"files": [{
"destination": "_theme.css",
"format": "css/variables"
}]
},
"android": {
"transformGroup": "android",
"buildPath": "build/android/",
"files": [{
"destination": "theme_colors.xml",
"format": "android/colors"
}]
},
"ios": {
"transformGroup": "ios-swift",
"buildPath": "build/ios/",
"files": [{
"destination": "Theme.swift",
"format": "ios-swift/class.swift"
}]
}
}
}
> **警告:** Theo 的 GitHub 仓库最后更新于 2021 年,存在已公布的 unescape 安全漏洞。如果选择 Theo,务必锁定版本 `2.0.5` 并手动 review transform 脚本。生产环境强烈建议迁移至 Style Dictionary。
## 2.3 云存储与 CDN 架构概览
构建产物(CSS / JSON / Compose 资源)需要部署到**对象存储 + CDN** 组成的云分发层,才能被终端应用按版本、按用户、按实验组动态加载。
**核心架构节点说明:**
| 组件 | 职责 | 选型参考 |
|------|------|----------|
| 对象存储 | 存储主题分发包(.css / .json / .zip) | AWS S3、阿里 OSS、腾讯 COS、MinIO |
| CDN 缓存 | 边缘节点缓存静态主题文件 | CloudFront、阿里 CDN、Cloudflare、AWS CloudFront |
| 版本管理 | 路由到 `latest` 或具体版本号 | 存储 key 命名:`theme/v1.2.3/web.css` |
| 鉴权签名 | 控制设计资源私密性 | AWS SigV4、阿里 STS、腾讯临时密钥 |
**工作流流程步骤:**
1. 设计端产出 `tokens.json` 提交到 Git 仓库的 `design/` 目录
2. CI/CD 构建阶段调用 **Style Dictionary** 命令生成平台产物
3. 产物上传至对象存储(如:`theme/v1.2.3/web.css`、`theme/v1.2.3/android/theme_colors.xml`)
4. CDN 回源拉取并缓存至全球边缘节点
5. 客户端 App 通过 API 或配置中心获取当前版本号,拼装 CDN URL 下载主题
**CDN 缓存策略关键参数:**
# CloudFront 行为配置节选
CachePolicy:
DefaultTTL: 86400 # 默认缓存 24 小时
MaxTTL: 604800 # 最大缓存 7 天
MinTTL: 0
ForwardedHeaders:
- Origin
- Access-Control-Request-Headers
# 建议启用压缩
Compress: true
# 跨域允许清单
CORS:
AllowedOrigins:
- "https://*.example.com"
> **提示:** 对象存储和 CDN 的配置切勿硬编码到前端代码中。建议通过应用启动时从**配置中心**或 **DNS 解析**获取 CDN 域名,实现迁移无感知。
## 2.4 内联 SVG: 从设计端到 CDN 分发的完整工作流
## 2.5 常见错误与调试
| 错误现象 | 可能原因 | 解决措施 |
|----------|----------|----------|
| Style Dictionary 构建后 CSS 变量名与设计端命名不一致 | Transform 组配置遗漏或顺序错误 | 检查 `transformGroup: "css"` 是否启用 name 转写 |
| CDN 文件更新后客户端仍读取旧主题 | CDN 缓存 TTL 过长或未主动刷新 | 使用版本号路径 + 强制刷新 CDN 缓存(如 `aws cloudfront create-invalidation`)|
| 对象存储 CORS 报错导致前端无法加载 | 存储桶 CORS 规则未配置 | 配置 `AllowedOrigins` 和 `AllowedHeaders` |
| JSON 中缺少 `$type` 字段 | 设计端忽略类型声明 | 在 Figma 插件输出时强制校验 schema |
**性能与稳定性优化要点:**
- 避免每个版本都全量发布。使用增量包或差分补丁机制,减少 CDN 回源负载。
- 设置 CDN 的 **Stale While Revalidate** 策略,确保回源失败时仍返回缓存数据。
- 对象存储启用 **多版本控制**(S3 Versioning),支持快速回滚至上一主题版本。
- 使用 **Content Hash** 作为文件名(如 `theme.a3f2c9.css`),实现长期缓存 + 即时更新。
> **提示:** 在 CI/CD 管道中增加 `curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone}/purge_cache"` 步骤,在每次部署后自动过期 CDN 缓存。