用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/wanghaisheng/openaiworkhorse-design-team --skill app-monorepo-react-pwa命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | app-monorepo-react-pwa |
| description | App应用Monorepo React PWA开发skill - 融合设计系统、类型安全、PWA特性的移动应用开发最佳实践 |
你是一位专注于移动应用Monorepo React PWA开发的专家架构师和设计师。你的职责是结合设计系统规范、类型安全原则、PWA特性和monorepo架构,创建可维护、可扩展的移动应用。
不适用场景:纯Web原型(使用web-html-prototype skill)、纯Web应用开发(使用web-monorepo-react skill)、纯原生App开发。
系统通过单一的"大脑"(packages/core)驱动所有端,通过"适配器"处理环境差异:
window、document或平台特有的全局变量IStorageAdapter接口操作数据vite-plugin-pwa管理离线生命周期Capacitor桥接原生插件(扫码、通知、地理位置)Virtua虚拟化渲染window、document或平台特有的全局变量SupabaseAdapter(云端)SqliteAdapter(PWA本地数据库)AsyncStorageAdapter(移动端轻量存储)IndexedDBAdapter(浏览器离线存储)// vite.config.ts
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico', 'apple-touch-icon.png'],
manifest: {
name: 'App Name',
short_name: 'App',
description: 'App Description',
theme_color: '#ffffff',
background_color: '#ffffff',
display: 'standalone',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
}
})
]
});
// packages/core/src/plugins/capacitor.ts
import { Camera } from '@capacitor/camera';
import { LocalNotifications } from '@capacitor/local-notifications';
import { Geolocation } from '@capacitor/geolocation';
import { BarcodeScanner } from '@capacitor/barcode-scanner';
// 相机
export async function takePhoto() {
const image = await Camera.getPhoto({
quality: 90,
allowEditing: false,
resultType: CameraResultType.Uri
});
return image.webPath;
}
// 通知
export async function scheduleNotification(title: string, body: string) {
await LocalNotifications.schedule({
notifications: [
{
title,
body,
id: new ().(),
: { : (.() + * ) }
}
]
});
}
() {
coordinates = .();
{
: coordinates..,
: coordinates..
};
}
() {
result = .();
.();
result.;
}
// Web环境降级
export async function takePhoto() {
try {
return await Camera.getPhoto({ /* ... */ });
} catch (error) {
// Web环境使用file input
return new Promise((resolve) => {
const input = document.createElement('input');
input.type = 'file';
input.accept = 'image/*';
input.onchange = (e) => resolve(e.target.files[0]);
input.click();
});
}
}
遵循移动端触控标准:
| 元素 | 最小尺寸 | 推荐 |
|---|---|---|
| 按钮 | 44×44pt | ≥60×60pt |
| 列表项 | 44pt高 | ≥48pt |
| 间距 | 8pt | ≥16pt |
支持多种设备尺寸:
| 设备 | 尺寸 | 用途 |
|---|---|---|
| iPhone 14 Pro | 393×852px | 默认 |
| iPhone 14 | 390×844px | 小屏 |
| iPhone 14 Plus | 430×932px | 大屏 |
| iPhone SE | 375×667px | 小屏兼容 |
| Android | 360×800px | Android默认 |
在原型阶段(使用app-html-prototype skill)时,如无法获取真实图片,可使用SVG Art占位符。
注意:生产环境开发阶段不使用SVG Art占位符,必须使用真实图片或设计系统资源。
详细指南见:app-html-prototype/SKILL.md 中的"SVG Art占位符指南"章节。
当任务涉及具体品牌时,必须执行核心资产协议:
| 资产类型 | 识别度贡献 | 必需性 |
|---|---|---|
| Logo | 最高 | 任何品牌都必须有 |
| UI截图/界面素材 | 极高 | 数字产品必须有 |
| 色值 | 中 | 辅助 |
| 字体 | 低 | 辅助 |
基于DESIGN-SPEC.md规范,适配移动端的设计令牌:
// packages/ui/src/tokens/mobile.ts
export const mobileTokens = {
colors: {
primary: '#1A1C1E',
secondary: '#6C7278',
tertiary: '#B8422E',
neutral: '#F7F5F2',
},
typography: {
h1: {
fontFamily: 'Inter',
fontSize: '32px',
fontWeight: 600,
lineHeight: 1.2,
},
bodyMd: {
fontFamily: 'Inter',
fontSize: '16px',
fontWeight: 400,
lineHeight: 1.5,
},
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
},
rounded: {
sm: '8px',
md: '12px',
lg: '16px',
},
// 移动端特定
touchTarget: {
min: '44px',
recommended: ,
},
} ;
基于设计令牌定制Ionic主题:
// packages/ui/src/theme/ionic.ts
import { IonicTheme } from '@ionic/react';
export const appTheme: IonicTheme = {
colors: {
primary: '#1A1C1E',
secondary: '#6C7278',
tertiary: '#B8422E',
success: '#2ecc71',
warning: '#f1c40f',
danger: '#e74c3c',
light: '#ecf0f1',
medium: '#95a5a6',
dark: '#34495e',
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
},
borderRadius: {
sm: '8px',
md: '12px',
lg: '16px',
},
};
系统以Schema为核心契约,实现端到端类型安全:
// packages/shared/src/schemas/user.ts
import { z } from 'zod';
export const UserSchema = z.object({
id: z.string().uuid(),
email: z.string().email(),
name: z.string().min(1).max(100),
createdAt: z.number(), // 平台无关的时间戳
updatedAt: z.number(),
});
export type User = z.infer<typeof UserSchema>;
所有API Action和存储操作必须返回统一的Result包装器:
type Result<T, E = AppError> =
| {
ok: true;
data: T;
source: 'server' | 'cache' | 'local' | 'bridge';
synced: boolean;
}
| { ok: false; error: E };
// packages/shared/src/types/mobile.ts
export interface DeviceInfo {
platform: 'ios' | 'android' | 'web';
model: string;
osVersion: string;
appVersion: string;
}
export interface Location {
lat: number;
lng: number;
accuracy?: number;
}
export interface NotificationPermission {
granted: boolean;
canRequest: boolean;
}
monorepo/
├── apps/
│ ├── pwa/ # Ionic + Capacitor PWA
│ │ ├── src/
│ │ │ ├── pages/ # 页面
│ │ │ ├── components/ # 组件
│ │ │ └── theme/ # 主题
│ │ ├── capacitor.config.ts # Capacitor配置
│ │ └── vite.config.ts # Vite配置
│ └── web/ # 移动端友好的Web应用
│ ├── src/
│ └── astro.config.mjs
├── packages/
│ ├── core/ # 核心业务逻辑
│ │ ├── src/
│ │ │ ├── procedures/ # 业务Procedures
│ │ │ ├── plugins/ # Capacitor插件封装
│ │ │ ├── utils/ # 工具函数
│ │ │ └── types/ # 类型定义
│ │ └── package.json
│ ├── ui/ # React/Ionic组件库
│ │ ├── src/
│ │ │ ├── components/ # 组件
│ │ │ ├── tokens/ # 设计令牌
│ │ │ └── theme/ # Ionic主题
│ │ └── package.json
│ ├── api/ # tRPC API
│ │ ├── src/
│ │ │ ├── router/ # tRPC路由
│ │ │ └── procedures/ # API Procedures
│ │ └── package.json
│ ├── storage/ # 存储适配器
│ │ ├── src/
│ │ │ ├── adapters/ # 适配器实现
│ │ │ │ ├── sqlite.ts # SQLite适配器
│ │ │ │ ├── indexeddb.ts # IndexedDB适配器
│ │ │ │ └── asyncstorage.ts # AsyncStorage适配器
│ │ │ └── interface.ts # 存储接口
│ │ └── package.json
│ ├── shared/ # 共享类型和Schema
│ │ ├── src/
│ │ │ ├── schemas/ # Zod Schema
│ │ │ ├── types/ # 共享类型
│ │ │ └── mobile/ # 移动端特定类型
│ │ └── package.json
│ └── config/ # 共享配置
│ ├── eslint/
│ ├── prettier/
│ └── tsconfig/
├── turbo.json # Turborepo配置
├── package.json # 根package.json
└── pnpm-workspace.yaml # PNPM workspace
Virtua虚拟化渲染规避AI训练语料里最常见的"视觉最大公约数":
核心要规避的:
#0D1117正向做什么:
any类型