@doubao-apps/ai 0.0.25 → 0.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/994.js +6 -6
- package/dist/contexts/doubao-apps-dev/.ai/examples/common-patterns.md +600 -0
- package/dist/contexts/doubao-apps-dev/.ai/examples/component-basics.md +509 -0
- package/dist/contexts/doubao-apps-dev/.ai/guides/best-practices.md +571 -0
- package/dist/contexts/doubao-apps-dev/.ai/guides/component-development.md +857 -0
- package/dist/contexts/doubao-apps-dev/.ai/guides/performance-optimization.md +404 -0
- package/dist/contexts/doubao-apps-dev/.ai/guides/system-prompt.md +331 -0
- package/dist/contexts/doubao-apps-dev/.ai/guides/troubleshooting.md +291 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/components-quick-ref.md +103 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/framework-api-quick-ref.md +537 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +699 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/02-/345/255/230/345/202/250.md +409 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/03-/350/267/257/347/224/261.md +165 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/04-/347/225/214/351/235/242-/344/272/244/344/272/222.md +432 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/07-/345/252/222/344/275/223.md +346 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/08-/345/274/200/346/224/276/350/203/275/345/212/233-/344/270/232/345/212/241/350/203/275/345/212/233.md +546 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md +961 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md +277 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api/README.md +36 -0
- package/dist/contexts/doubao-apps-dev/.ai/reference/open-api.md +326 -0
- package/dist/contexts/doubao-apps-dev/.ai/rules/dos-and-donts.md +390 -0
- package/dist/{skills → contexts}/doubao-apps-dev/AGENTS.md +56 -33
- package/dist/{skills → contexts}/doubao-apps-dev/CLAUDE.md +1 -1
- package/dist/manifest.json +45 -0
- package/dist/skills/doubao-apps-dev/.ai/examples/common-patterns.md +53 -43
- package/dist/skills/doubao-apps-dev/.ai/examples/component-basics.md +0 -17
- package/dist/skills/doubao-apps-dev/.ai/guides/component-development.md +96 -214
- package/dist/skills/doubao-apps-dev/.ai/guides/system-prompt.md +14 -14
- package/dist/skills/doubao-apps-dev/.ai/reference/framework-api-quick-ref.md +46 -85
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/01-/345/237/272/347/241/200-/350/264/246/345/217/267-/347/263/273/347/273/237.md +699 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/02-/345/255/230/345/202/250.md +409 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/03-/350/267/257/347/224/261.md +165 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/04-/347/225/214/351/235/242-/344/272/244/344/272/222.md +432 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/05-/347/225/214/351/235/242-/350/276/223/345/205/245.md +42 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/06-/347/275/221/347/273/234.md +148 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/07-/345/252/222/344/275/223.md +346 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/08-/345/274/200/346/224/276/350/203/275/345/212/233-/344/270/232/345/212/241/350/203/275/345/212/233.md +546 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/09-/350/256/276/345/244/207-/350/223/235/347/211/231.md +961 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/10-/350/256/276/345/244/207-wi-fi.md +277 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/11-/350/256/276/345/244/207-/345/212/240/351/200/237/345/272/246/350/256/241.md +104 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/12-/350/256/276/345/244/207-ibeacon.md +148 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/13-/350/256/276/345/244/207-/347/275/227/347/233/230.md +82 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/14-/350/256/276/345/244/207-/350/256/276/345/244/207/346/226/271/345/220/221.md +70 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/15-/350/256/276/345/244/207-/351/231/200/350/236/272/344/273/252.md +104 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/16-ui-/350/276/223/345/205/245.md +65 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/17-/350/256/276/345/244/207-/347/275/221/347/273/234.md +164 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/18-/350/256/276/345/244/207-/347/237/255/344/277/241.md +62 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/19-/350/256/276/345/244/207-/346/227/240/351/232/234/347/242/215.md +43 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/20-/350/256/276/345/244/207-/347/224/265/346/261/240.md +83 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/21-/350/256/276/345/244/207-/346/227/245/345/216/206.md +215 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/22-/350/256/276/345/244/207-/345/211/252/350/264/264/346/235/277.md +70 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/23-/350/256/276/345/244/207-/350/201/224/347/263/273/344/272/272.md +270 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/24-/350/256/276/345/244/207-/345/212/240/345/257/206.md +56 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/25-/350/256/276/345/244/207-/347/224/265/350/257/235.md +41 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/26-/350/256/276/345/244/207-/346/211/253/347/240/201.md +100 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/27-/350/256/276/345/244/207-/345/261/217/345/271/225.md +173 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/28-/350/256/276/345/244/207-/351/234/207/345/212/250.md +66 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api/README.md +36 -0
- package/dist/skills/doubao-apps-dev/.ai/reference/open-api.md +267 -4542
- package/dist/skills/doubao-apps-dev/.ai/rules/dos-and-donts.md +50 -37
- package/dist/skills/doubao-apps-dev/SKILL.md +57 -29
- package/dist/skills/douyin-to-doubao/SKILL.md +2 -2
- package/dist/skills/h5-to-doubao/SKILL.md +2 -2
- package/dist/skills/uniapp-to-doubao/SKILL.md +2 -2
- package/dist/skills/weixin-to-doubao/SKILL.md +2 -2
- package/package.json +4 -2
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
# 开发规则 - Do's and Don'ts
|
|
2
|
+
|
|
3
|
+
Doubao Apps SDK 框架的开发规则和最佳实践。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ✅ 推荐做法(Do's)
|
|
8
|
+
|
|
9
|
+
### 项目管理
|
|
10
|
+
|
|
11
|
+
#### ✅ 使用 pnpm 包管理器
|
|
12
|
+
```bash
|
|
13
|
+
# 推荐
|
|
14
|
+
pnpm install
|
|
15
|
+
pnpm add @doubao-apps/framework
|
|
16
|
+
|
|
17
|
+
# 不推荐(除非项目已使用 npm)
|
|
18
|
+
npm install
|
|
19
|
+
npm install @doubao-apps/framework
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### 组件开发
|
|
24
|
+
|
|
25
|
+
#### ✅ 定义完整的 aiMeta
|
|
26
|
+
```tsx
|
|
27
|
+
// ✅ 好的做法
|
|
28
|
+
export default definePage({
|
|
29
|
+
aiMeta: {
|
|
30
|
+
id: 'user-profile',
|
|
31
|
+
title: '用户资料',
|
|
32
|
+
description: '展示和编辑用户个人资料'
|
|
33
|
+
},
|
|
34
|
+
// ...
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
// ❌ 不好的做法
|
|
40
|
+
export default definePage({
|
|
41
|
+
aiMeta: {
|
|
42
|
+
id: 'page1' // 缺少 title、description 等信息
|
|
43
|
+
},
|
|
44
|
+
// ...
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### ✅ 分离样式文件
|
|
49
|
+
```tsx
|
|
50
|
+
// ✅ 好的做法
|
|
51
|
+
// index.tsx
|
|
52
|
+
import './index.scss';
|
|
53
|
+
|
|
54
|
+
export default definePage({
|
|
55
|
+
// ...
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```scss
|
|
60
|
+
// index.scss
|
|
61
|
+
.container {
|
|
62
|
+
padding: 16px;
|
|
63
|
+
background: #fff;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
// ❌ 不好的做法
|
|
69
|
+
export default definePage({
|
|
70
|
+
render() {
|
|
71
|
+
return (
|
|
72
|
+
<view style={{ padding: '16px', background: '#fff' }}>
|
|
73
|
+
内容
|
|
74
|
+
</view>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
#### ✅ 使用 TypeScript 类型定义
|
|
81
|
+
```tsx
|
|
82
|
+
// ✅ 好的做法
|
|
83
|
+
interface UserInfo {
|
|
84
|
+
name: string;
|
|
85
|
+
age: number;
|
|
86
|
+
avatar?: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export default defineWidget({
|
|
90
|
+
render() {
|
|
91
|
+
const input = getViewData<UserInfo>();
|
|
92
|
+
return <view>{input.name}</view>;
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
// ✅ 把 metadata 写到 src/app.config.ts
|
|
99
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
100
|
+
|
|
101
|
+
export default defineAppConfig({
|
|
102
|
+
widgets: {
|
|
103
|
+
'widgets/user-card': {
|
|
104
|
+
id: 'user-card',
|
|
105
|
+
name: '用户卡片',
|
|
106
|
+
description: '用户信息卡片'
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
// ❌ 不好的做法
|
|
114
|
+
export default defineWidget({
|
|
115
|
+
render() {
|
|
116
|
+
const input = getViewData<any>(); // 使用 any 类型,失去类型检查
|
|
117
|
+
return <view>{input.name}</view>;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### ✅ 使用生命周期钩子
|
|
123
|
+
```tsx
|
|
124
|
+
// ✅ 好的做法
|
|
125
|
+
export default definePage({
|
|
126
|
+
aiMeta: { /* ... */ },
|
|
127
|
+
|
|
128
|
+
onShow() {
|
|
129
|
+
console.log('Page shown');
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
onHide() {
|
|
133
|
+
console.log('Page hidden');
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
onDestroy() {
|
|
137
|
+
console.log('Page destroyed');
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
render() {
|
|
141
|
+
return <view>内容</view>;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
#### ✅ 错误处理和边界情况
|
|
148
|
+
```tsx
|
|
149
|
+
// ✅ 好的做法
|
|
150
|
+
export default defineWidget({
|
|
151
|
+
render() {
|
|
152
|
+
const input = getViewData<{ items: string[] }>();
|
|
153
|
+
// 处理空数据
|
|
154
|
+
if (!input.items || input.items.length === 0) {
|
|
155
|
+
return <view>暂无数据</view>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<view>
|
|
160
|
+
{input.items.map((item, index) => (
|
|
161
|
+
<view key={index}>{item}</view>
|
|
162
|
+
))}
|
|
163
|
+
</view>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
// ❌ 不好的做法
|
|
171
|
+
export default defineWidget({
|
|
172
|
+
render() {
|
|
173
|
+
const input = getViewData<any>();
|
|
174
|
+
// 没有检查 input.items 是否存在
|
|
175
|
+
return (
|
|
176
|
+
<view>
|
|
177
|
+
{input.items.map(item => <view>{item}</view>)}
|
|
178
|
+
</view>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## ❌ 禁止做法(Don'ts)
|
|
187
|
+
|
|
188
|
+
### 样式相关
|
|
189
|
+
|
|
190
|
+
#### ❌ 内联样式长度值必须带单位
|
|
191
|
+
|
|
192
|
+
Lynx CSS encoder 要求:**所有 CSS 长度值必须显式带单位**,裸数字(无单位)会触发运行时错误 `CSS length need units (except 0)`。
|
|
193
|
+
|
|
194
|
+
```tsx
|
|
195
|
+
// ❌ 错误:裸数字(无单位)
|
|
196
|
+
<view style={{ width: 100, height: 56, fontSize: 14 }} />
|
|
197
|
+
|
|
198
|
+
// ✅ 正确:带单位字符串
|
|
199
|
+
<view style={{ width: '100px', height: '56px', fontSize: '14px' }} />
|
|
200
|
+
|
|
201
|
+
// ✅ 例外:以下属性可以使用裸数字(无单位)
|
|
202
|
+
// flex, opacity, zIndex, fontWeight, aspectRatio
|
|
203
|
+
<view style={{ flex: 1, opacity: 0.5, zIndex: 10 }} />
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
#### ❌ 不写内联样式
|
|
207
|
+
```tsx
|
|
208
|
+
// ❌ 错误
|
|
209
|
+
export default definePage({
|
|
210
|
+
render() {
|
|
211
|
+
return (
|
|
212
|
+
<view style={{ padding: 16, background: '#fff' }}>
|
|
213
|
+
内容
|
|
214
|
+
</view>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
// ✅ 正确
|
|
222
|
+
import './index.scss';
|
|
223
|
+
|
|
224
|
+
export default definePage({
|
|
225
|
+
render() {
|
|
226
|
+
return (
|
|
227
|
+
<view className="container">
|
|
228
|
+
内容
|
|
229
|
+
</view>
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### 异步操作
|
|
236
|
+
|
|
237
|
+
#### ❌ 不在 render 中发起请求
|
|
238
|
+
```tsx
|
|
239
|
+
// ❌ 错误 - 每次渲染都会发请求
|
|
240
|
+
export default definePage({
|
|
241
|
+
render() {
|
|
242
|
+
fetch('/api/data').then(data => {
|
|
243
|
+
// 处理数据
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
return <view>内容</view>;
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
// ✅ 推荐 - 使用 Hook 管理请求和状态
|
|
253
|
+
import { useEffect, useState } from '@doubao-apps/framework';
|
|
254
|
+
|
|
255
|
+
function UserPage() {
|
|
256
|
+
const [userData, setUserData] = useState<{ name?: string } | null>(null);
|
|
257
|
+
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
fetch('/api/data')
|
|
260
|
+
.then(res => res.json())
|
|
261
|
+
.then(data => {
|
|
262
|
+
setUserData(data);
|
|
263
|
+
});
|
|
264
|
+
}, []);
|
|
265
|
+
|
|
266
|
+
return <view>{userData?.name}</view>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
export default definePage({
|
|
270
|
+
render() {
|
|
271
|
+
return <UserPage />;
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 组件结构
|
|
277
|
+
|
|
278
|
+
#### ❌ 不过度嵌套组件
|
|
279
|
+
```tsx
|
|
280
|
+
// ❌ 错误 - 过度嵌套
|
|
281
|
+
export default definePage({
|
|
282
|
+
render() {
|
|
283
|
+
return (
|
|
284
|
+
<view>
|
|
285
|
+
<view>
|
|
286
|
+
<view>
|
|
287
|
+
<view>
|
|
288
|
+
<view>
|
|
289
|
+
<view>
|
|
290
|
+
内容
|
|
291
|
+
</view>
|
|
292
|
+
</view>
|
|
293
|
+
</view>
|
|
294
|
+
</view>
|
|
295
|
+
</view>
|
|
296
|
+
</view>
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
// ✅ 正确 - 扁平结构
|
|
304
|
+
export default definePage({
|
|
305
|
+
render() {
|
|
306
|
+
return (
|
|
307
|
+
<view className="page">
|
|
308
|
+
<view className="header">头部</view>
|
|
309
|
+
<view className="content">内容</view>
|
|
310
|
+
<view className="footer">底部</view>
|
|
311
|
+
</view>
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 类型使用
|
|
318
|
+
|
|
319
|
+
#### ❌ 不忽略 TypeScript 类型
|
|
320
|
+
```tsx
|
|
321
|
+
// ❌ 错误
|
|
322
|
+
export default defineWidget({
|
|
323
|
+
render() {
|
|
324
|
+
const input = getViewData<any>();
|
|
325
|
+
// @ts-ignore
|
|
326
|
+
return <view>{input.unknownProperty}</view>;
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
// ✅ 正确
|
|
333
|
+
interface Input {
|
|
334
|
+
name: string;
|
|
335
|
+
age: number;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
export default defineWidget({
|
|
339
|
+
render() {
|
|
340
|
+
const input = getViewData<Input>();
|
|
341
|
+
return <view>{input.name}</view>;
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### 状态管理
|
|
347
|
+
|
|
348
|
+
#### ❌ 不在全局作用域定义状态
|
|
349
|
+
```tsx
|
|
350
|
+
// ❌ 错误 - 全局变量会在多个实例间共享
|
|
351
|
+
let count = 0;
|
|
352
|
+
|
|
353
|
+
export default defineWidget({
|
|
354
|
+
render() {
|
|
355
|
+
count++; // 所有实例共享这个 count
|
|
356
|
+
return <view>Count: {count}</view>;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
// ✅ 推荐 - 使用组件内状态,实例之间互不影响
|
|
363
|
+
import { useState } from '@doubao-apps/framework';
|
|
364
|
+
|
|
365
|
+
function CounterWidget() {
|
|
366
|
+
const [count, setCount] = useState(0);
|
|
367
|
+
|
|
368
|
+
return (
|
|
369
|
+
<view
|
|
370
|
+
onClick={() => {
|
|
371
|
+
setCount(prev => prev + 1);
|
|
372
|
+
}}
|
|
373
|
+
>
|
|
374
|
+
Count: {count}
|
|
375
|
+
</view>
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
export default defineWidget({
|
|
380
|
+
render() {
|
|
381
|
+
return <CounterWidget />;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
## 📚 相关文档
|
|
387
|
+
|
|
388
|
+
- [组件开发指南](../guides/component-development.md)
|
|
389
|
+
- [最佳实践](../guides/best-practices.md)
|
|
390
|
+
- [性能优化](../guides/performance-optimization.md)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Doubao Apps SDK AI 开发指南
|
|
2
2
|
|
|
3
3
|
本文件专供 AI coding agents(如 Claude、Copilot、Cursor)和开发者使用,提供 Doubao Apps SDK 框架的快速入门、开发规则和文档导航。
|
|
4
4
|
|
|
@@ -31,7 +31,6 @@ pnpm install
|
|
|
31
31
|
|
|
32
32
|
# 启动开发
|
|
33
33
|
pnpm dev
|
|
34
|
-
|
|
35
34
|
```
|
|
36
35
|
|
|
37
36
|
**开发服务器命令**:
|
|
@@ -67,9 +66,9 @@ my-doubao-app/
|
|
|
67
66
|
|
|
68
67
|
- **优先使用 pnpm** 作为包管理器
|
|
69
68
|
- **分离样式文件**:每个组件使用独立的 `.scss` 文件
|
|
70
|
-
-
|
|
69
|
+
- **在 `src/app.config.ts` 中配置 metadata**:为 App、Page 和 Widget 统一配置元数据
|
|
71
70
|
- **使用生命周期钩子**:合理使用 `onShow`、`onMounted` 等
|
|
72
|
-
- **TypeScript
|
|
71
|
+
- **TypeScript 类型**:使用 `getViewData<T>()`、为 props 和 state 提供类型定义
|
|
73
72
|
- **错误处理**:处理边界情况和错误状态
|
|
74
73
|
|
|
75
74
|
### 禁止做法
|
|
@@ -93,22 +92,37 @@ my-doubao-app/
|
|
|
93
92
|
|
|
94
93
|
Page 是全屏 UI 组件,支持九宫格、浮窗等变体。
|
|
95
94
|
|
|
96
|
-
|
|
95
|
+
**metadata 配置**:
|
|
96
|
+
```ts
|
|
97
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
98
|
+
|
|
99
|
+
export default defineAppConfig({
|
|
100
|
+
pages: {
|
|
101
|
+
'pages/home': {
|
|
102
|
+
id: 'my-page',
|
|
103
|
+
title: '我的页面',
|
|
104
|
+
description: '页面功能描述'
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**页面实现**:
|
|
97
111
|
```tsx
|
|
98
112
|
import { definePage, getViewData } from '@doubao-apps/framework';
|
|
99
113
|
import './index.scss';
|
|
100
114
|
|
|
115
|
+
interface HomePageData {
|
|
116
|
+
title: string;
|
|
117
|
+
}
|
|
118
|
+
|
|
101
119
|
export default definePage({
|
|
102
|
-
aiMeta: {
|
|
103
|
-
id: 'my-page',
|
|
104
|
-
title: '我的页面',
|
|
105
|
-
},
|
|
106
120
|
onShow() {
|
|
107
121
|
// 页面显示时触发
|
|
108
122
|
},
|
|
109
123
|
render() {
|
|
110
|
-
const input = getViewData();
|
|
111
|
-
return <view
|
|
124
|
+
const input = getViewData<HomePageData>();
|
|
125
|
+
return <view>{input.title}</view>;
|
|
112
126
|
}
|
|
113
127
|
});
|
|
114
128
|
```
|
|
@@ -119,28 +133,38 @@ export default definePage({
|
|
|
119
133
|
|
|
120
134
|
Widget 是聊天流中的卡片组件,在对话中展示。
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
**metadata 配置**:
|
|
137
|
+
```ts
|
|
138
|
+
import { defineAppConfig } from '@doubao-apps/kit';
|
|
139
|
+
|
|
140
|
+
export default defineAppConfig({
|
|
141
|
+
widgets: {
|
|
142
|
+
'widgets/my-widget': {
|
|
143
|
+
id: 'my-widget',
|
|
144
|
+
name: '我的卡片',
|
|
145
|
+
description: '卡片功能描述',
|
|
146
|
+
boxType: 'inbox',
|
|
147
|
+
border: true
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**卡片实现**:
|
|
123
154
|
```tsx
|
|
124
155
|
import { defineWidget, getViewData } from '@doubao-apps/framework';
|
|
125
156
|
import './index.scss';
|
|
126
157
|
|
|
158
|
+
interface MyWidgetData {
|
|
159
|
+
title: string;
|
|
160
|
+
}
|
|
161
|
+
|
|
127
162
|
export default defineWidget({
|
|
128
|
-
aiMeta: {
|
|
129
|
-
id: 'my-widget',
|
|
130
|
-
name: '我的卡片',
|
|
131
|
-
boxType: 'inbox',
|
|
132
|
-
input: {
|
|
133
|
-
type: 'object',
|
|
134
|
-
properties: {
|
|
135
|
-
title: { type: 'string', title: '标题' }
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
163
|
onMounted() {
|
|
140
164
|
// 卡片挂载后触发
|
|
141
165
|
},
|
|
142
166
|
render() {
|
|
143
|
-
const input = getViewData();
|
|
167
|
+
const input = getViewData<MyWidgetData>();
|
|
144
168
|
return <view>{input.title}</view>;
|
|
145
169
|
}
|
|
146
170
|
});
|
|
@@ -172,7 +196,7 @@ export default defineWidget({
|
|
|
172
196
|
完整的 Framework API(框架核心)和 Bridge API(系统能力)列表:
|
|
173
197
|
|
|
174
198
|
- **[Framework API 快速参考](.ai/reference/framework-api-quick-ref.md)** - 核心 Framework API 速查
|
|
175
|
-
- **[Open API
|
|
199
|
+
- **[Open API 目录](.ai/reference/open-api/README.md)** - 公开可用的端能力(系统能力)目录与详细文档
|
|
176
200
|
- **[组件库快速参考](.ai/reference/components-quick-ref.md)** - SDK 内置组件(Button、Switch、Swiper 等)
|
|
177
201
|
|
|
178
202
|
包含:
|
|
@@ -207,8 +231,7 @@ API 参考文档
|
|
|
207
231
|
|
|
208
232
|
- **[Framework API](.ai/reference/framework-api-quick-ref.md)** - 核心 Framework API 速查
|
|
209
233
|
- **[组件库](.ai/reference/components-quick-ref.md)** - SDK 内置组件速查
|
|
210
|
-
- **[Open API](.ai/reference/open-api.md)** - 系统能力 API
|
|
211
|
-
|
|
234
|
+
- **[Open API](.ai/reference/open-api/README.md)** - 系统能力 API 目录与详细文档
|
|
212
235
|
|
|
213
236
|
### 依赖包
|
|
214
237
|
|
|
@@ -244,10 +267,10 @@ API 参考文档
|
|
|
244
267
|
|
|
245
268
|
```
|
|
246
269
|
项目根目录/
|
|
247
|
-
├── AGENTS.md
|
|
248
|
-
└── .ai/
|
|
249
|
-
├── guides/
|
|
250
|
-
├── rules/
|
|
251
|
-
├── examples/
|
|
252
|
-
└── reference/
|
|
270
|
+
├── AGENTS.md # 主入口文档(AI Agent 必读)
|
|
271
|
+
└── .ai/ # 详细文档目录
|
|
272
|
+
├── guides/ # 开发指南
|
|
273
|
+
├── rules/ # 开发规则
|
|
274
|
+
├── examples/ # 代码示例
|
|
275
|
+
└── reference/ # API 参考
|
|
253
276
|
```
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
| 性能优化 | [.ai/guides/performance-optimization.md](.ai/guides/performance-optimization.md) |
|
|
17
17
|
| 问题排查 | [.ai/guides/troubleshooting.md](.ai/guides/troubleshooting.md) |
|
|
18
18
|
| Framework API | [.ai/reference/framework-api-quick-ref.md](.ai/reference/framework-api-quick-ref.md) |
|
|
19
|
-
| Bridge API / 系统能力 | [.ai/reference/open-api.md](.ai/reference/open-api.md) |
|
|
19
|
+
| Bridge API / 系统能力 | [.ai/reference/open-api/README.md](.ai/reference/open-api/README.md) |
|
|
20
20
|
|
|
21
21
|
## 知识库结构
|
|
22
22
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"packageName": "@byted-doubao-apps/ai-assets",
|
|
3
|
+
"version": "0.0.27",
|
|
4
|
+
"generatedAt": "2026-05-12T09:32:17.292Z",
|
|
5
|
+
"skills": [
|
|
6
|
+
{
|
|
7
|
+
"name": "doubao-apps-dev",
|
|
8
|
+
"entry": "skills/doubao-apps-dev/SKILL.md",
|
|
9
|
+
"hasAiDir": true
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"name": "douyin-to-doubao",
|
|
13
|
+
"entry": "skills/douyin-to-doubao/SKILL.md",
|
|
14
|
+
"hasAiDir": false
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"name": "h5-to-doubao",
|
|
18
|
+
"entry": "skills/h5-to-doubao/SKILL.md",
|
|
19
|
+
"hasAiDir": false
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "quality-gate",
|
|
23
|
+
"entry": "skills/quality-gate/SKILL.md",
|
|
24
|
+
"hasAiDir": false
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "uniapp-to-doubao",
|
|
28
|
+
"entry": "skills/uniapp-to-doubao/SKILL.md",
|
|
29
|
+
"hasAiDir": false
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "weixin-to-doubao",
|
|
33
|
+
"entry": "skills/weixin-to-doubao/SKILL.md",
|
|
34
|
+
"hasAiDir": false
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"contexts": [
|
|
38
|
+
{
|
|
39
|
+
"name": "doubao-apps-dev",
|
|
40
|
+
"entry": "contexts/doubao-apps-dev/AGENTS.md",
|
|
41
|
+
"claudeEntry": "contexts/doubao-apps-dev/CLAUDE.md",
|
|
42
|
+
"hasAiDir": true
|
|
43
|
+
}
|
|
44
|
+
]
|
|
45
|
+
}
|