feat: add taro h5 runtime deployment config

This commit is contained in:
Codex
2026-06-30 01:19:14 +08:00
parent b8242429bb
commit 25d1b8e796
16 changed files with 370 additions and 78 deletions

View File

@@ -1,13 +1,15 @@
# Taro H5 三入口部署说明
更新时间2026-06-29
更新时间2026-06-30
当前 `apps/taro` 一个 Taro 工程、三套 H5 产物组织
当前 `apps/taro` 采用一个 Taro 4 React 工程、三套 H5 产物的方式交付
- 学生学习端:刷题、背单词、知识手册、分数线、资料、会员个人中心。
- 租户后台:品牌、域名、题库、导入、学生、订单、营销、销售和数据看板。
- 学生学习端:刷题、背单词、知识手册、分数线、资料、会员个人中心。
- 租户后台:品牌、主题、域名、题库、导入、学生、订单、营销、销售、CRM、财务和数据看板。
- 平台后台租户、SaaS 套餐、订阅账单、公共题库授权和平台审计。
后续微信小程序仍复用同一套业务 services 和页面逻辑,但 H5 是当前优先上线形态。
## 构建命令
```bash
@@ -26,27 +28,55 @@ apps/taro/dist/h5-platform-admin
推荐部署:
| 域名 | 目录 | 说明 |
| 域名 | 静态目录 | 说明 |
| --- | --- | --- |
| `www.example.com` 或租户自有学生端域名 | `h5-student` | 面向学生和 C 端用户 |
| `admin.example.com` | `h5-tenant-admin` | 面向租户公司运营、教师、销售、代理、管理员 |
| `console.example.com` | `h5-platform-admin` | 面向平台超级管理员 |
三个入口可以放在同一台服务器的三个静态目录,也可以放到 CDN/对象存储静态网站。API 推荐独立域名,例如 `api.example.com`
三个入口可以放在同一台服务器的三个静态目录,也可以分别放到不同服务器或 CDN/对象存储静态网站。API 推荐独立域名,例如 `api.example.com`
## 环境变量
## 运行时配置
构建时只允许注入
H5 产物支持运行时覆盖公开配置。每个静态目录根部放一个 `runtime-config.json`
```text
TARO_APP_PORTAL=student | tenant-admin | platform-admin
TARO_APP_API_BASE_URL=https://api.example.com
TARO_APP_SUPABASE_URL=https://<supabase-auth-host>
TARO_APP_SUPABASE_PUBLISHABLE_KEY=<publishable-key>
TARO_APP_TENANT_CODE=<可选,小程序或预览环境使用>
/www/tiku/h5-student/runtime-config.json
/www/tiku/h5-tenant-admin/runtime-config.json
/www/tiku/h5-platform-admin/runtime-config.json
```
禁止进入前端构建
示例文件
```text
apps/taro/deploy/h5-student.runtime-config.example.json
apps/taro/deploy/h5-tenant-admin.runtime-config.example.json
apps/taro/deploy/h5-platform-admin.runtime-config.example.json
```
生产示例:
```json
{
"portal": "student",
"apiBaseUrl": "https://api.example.com",
"supabaseUrl": "https://auth.example.com",
"supabasePublishableKey": "replace-with-supabase-publishable-key",
"tenantCode": ""
}
```
允许字段:
```text
portal student | tenant-admin | platform-admin
apiBaseUrl apps/api 公开 HTTPS 地址
supabaseUrl Supabase Auth/API 公开 HTTPS 地址
supabasePublishableKey Supabase publishable/anon key
tenantCode 小程序、预览环境或指定租户部署可用
```
这些字段是前端公开配置,不是密钥。`apps/taro/src/env.ts` 会拒绝 `runtime-config.json` 中出现服务端密钥类字段,例如:
```text
SUPABASE_SERVICE_ROLE_KEY
@@ -60,34 +90,32 @@ AUTH_SESSION_SECRET
PLATFORM_ADMIN_API_KEY
```
`apps/taro/src/env.ts` 会在启动时检查这些危险变量,防止误把服务端密钥打包到前端
构建时仍可以设置同名 `TARO_APP_*` 变量作为默认值,但生产更推荐用 `runtime-config.json`。这样 API 域名、Auth 域名、租户预览码变化时不需要重新构建 H5
## Nginx 建议
## Nginx 示例
H5 使用 history 路由时,静态服务器需要把未知路径回退到 `index.html`
H5 使用 browser history 路由时,静态服务器需要把未知路径回退到 `index.html`同时对 `runtime-config.json` 禁用缓存,对 hash 后的 JS/CSS 长缓存。
```nginx
server {
listen 443 ssl http2;
server_name www.example.com;
root /www/tiku/h5-student;
location / {
try_files $uri $uri/ /index.html;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https: blob:; font-src 'self' data:; connect-src 'self' https://api.example.com https://auth.example.com; media-src 'self' https: blob:; frame-ancestors 'none'; base-uri 'self'; form-action 'self'" always;
location = /runtime-config.json {
add_header Cache-Control "no-store" always;
try_files $uri =404;
}
}
server {
server_name admin.example.com;
root /www/tiku/h5-tenant-admin;
location / {
try_files $uri $uri/ /index.html;
location ~* \.(?:js|css|woff2?|png|jpg|jpeg|gif|svg)$ {
add_header Cache-Control "public, max-age=31536000, immutable" always;
try_files $uri =404;
}
}
server {
server_name console.example.com;
root /www/tiku/h5-platform-admin;
location / {
try_files $uri $uri/ /index.html;
@@ -95,35 +123,78 @@ server {
}
```
API CORS 必须只允许实际域名,不允许生产环境 `CORS=*`。生产前运行:
租户后台和平台后台复用同样规则,替换 `server_name``root` 和 CSP 中的 `connect-src` 域名即可。若学生端需要打开 OSS/COS/CDN 签名资源,`img-src/media-src` 可加入对应 HTTPS 域名;不要加入通配符 `*`
```bash
npm run readiness:production
npm run readiness:production:db
## CORS 和 Cookie
API 的生产 `CORS_ORIGIN` 必须只包含实际前端域名:
```text
CORS_ORIGIN=https://www.example.com,https://admin.example.com,https://console.example.com
```
禁止生产环境使用:
```text
CORS_ORIGIN=*
```
当前前端以 `Authorization: Bearer <supabase_access_token 或 tk_session>` 调用 API`x-tenant-id` 只作为租户上下文,不作为身份来源。生产建议:
```text
ALLOW_LEGACY_AUTH_HEADERS=false
ALLOW_PLATFORM_ADMIN_KEY=false
```
## 前端请求边界
- 所有页面统一通过 `apps/taro/src/services/api.ts` 调用后端。
- H5 可以用 Supabase client 管理 Auth session但业务数据默认走 `apps/api`
- `x-tenant-id` 只是租户上下文,不是身份来源。
- 登录后禁止传 `x-user-id` 或 body/query `userId` 表示当前用户。
- H5 可以用 Supabase client 管理 Auth session/JWT,但业务数据默认走 `apps/api`
- 订单、支付、权益、内容导入、后台配置、CRM、对象存储签名、视频播放签名必须走后端命令层。
- 登录后禁止传 `x-user-id` 或 body/query `userId` 表示当前用户。
- 私有 PDF、图片、视频不能由前端拼接 URL必须使用 `content_assets` 和后端短签名。
## 发布步骤
1. 在新服务器或 CI 环境构建三套 H5
```bash
npm ci
npm run build:taro:h5:student
npm run build:taro:h5:tenant
npm run build:taro:h5:platform
```
2. 拷贝静态产物到对应 Web 根目录。
3. 根据示例文件创建每个目录的 `runtime-config.json`。
4. 配置 Nginx history fallback、缓存策略、安全响应头和 HTTPS。
5. 配置 API 的 `CORS_ORIGIN`、Supabase Auth 回调域名、微信/QQ/支付宝/微信支付回调域名。
6. 运行生产就绪检查:
```bash
npm run readiness:production
npm run readiness:production:db
npm run check:taro
```
7. 打开三个域名,确认启动页能解析租户,登录后接口请求使用 `Authorization` 和正确的 `x-tenant-id`。
## 安全审计边界
H5 线上只发布 `apps/taro/dist/**` 静态文件,不要把 `apps/taro/node_modules` 或源码目录部署到 Web 根目录。后端/API/worker 的生产依赖审计使用:
H5 线上只发布 `apps/taro/dist/**` 静态文件和每个目录自己的 `runtime-config.json`,不要把 `apps/taro/node_modules`、源码目录、`.env`、部署脚本缓存放进 Web 根目录。
后端/API/worker 的生产依赖审计使用:
```bash
npm run audit:runtime
```
Taro 4.2.0 当前构建工具链仍触发 `npm run audit:taro:toolchain` 的上游 high/critical 告警,主要来自构建期 CLI、webpack、swiper、lodash-es 等传递依赖。不要使用 `npm audit fix --force` 将 Taro 降级到 3.x应等 Taro 官方升级后再处理,或后续评估 Vite runner 替代方案。上线时以静态产物、前端密钥检查、CORS 域名白名单和 API runtime audit 作为阻断项。
Taro 4.2.0 当前构建工具链仍可能触发 `npm run audit:taro:toolchain` 的上游 high/critical 告警,主要来自构建期 CLI、webpack、swiper、lodash-es 等传递依赖。不要使用 `npm audit fix --force` 将 Taro 降级到 3.x应等 Taro 官方升级后再处理,或后续评估 Vite runner 替代方案。上线时以静态产物、前端密钥检查、CORS 域名白名单、CSP 和 API runtime audit 作为阻断项。
## 下一步页面顺序
## 小程序后续兼容
1. 学生端:租户启动、登录、首页、题库入口、练习、错题、收藏
2. 学生端:背单词、知识手册、分数线、资料、会员、个人中心。
3. 租户后台:数据看板、内容导航、题目录入/导入、学生管理、营销中心。
4. 平台后台:租户、套餐、账单、公共题库授权。
5. 小程序:验证 storage/fetch/Auth 兼容性,复用同一套 API client。
当前 `runtime-config.json` 只用于 H5。微信小程序版本应通过编译变量、小程序启动参数或后台小程序配置传入 `tenantCode`,再调用 `GET /api/tenant/resolve?tenantCode=...`。小程序端如 `supabase-js` 兼容性不稳定,保留 `apps/api/auth/*` 登录适配层H5 继续使用 Supabase client 管理 Auth。