@doubao-apps/ai 0.0.19 → 0.0.20
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/dist/skills/doubao-apps-dev/.ai/reference/open-api.md +94 -2
- package/dist/skills/douyin-to-doubao/SKILL.md +333 -0
- package/dist/skills/douyin-to-doubao/assets/migration-checklist-template.md +144 -0
- package/dist/skills/douyin-to-doubao/references/mapping/component-mapping.md +200 -0
- package/dist/skills/douyin-to-doubao/references/mapping/core-api-mapping.md +231 -0
- package/dist/skills/douyin-to-doubao/references/mapping/event-mapping.md +196 -0
- package/dist/skills/douyin-to-doubao/references/mapping/lifecycle-mapping.md +216 -0
- package/dist/skills/douyin-to-doubao/references/mapping/style-mapping.md +195 -0
- package/dist/skills/douyin-to-doubao/references/source-framework/api-reference.md +223 -0
- package/dist/skills/douyin-to-doubao/references/source-framework/components.md +252 -0
- package/dist/skills/h5-to-doubao/SKILL.md +9 -7
- package/dist/skills/weixin-to-doubao/SKILL.md +18 -38
- package/dist/skills/weixin-to-doubao/assets/migration-checklist-template.md +11 -7
- package/dist/skills/weixin-to-doubao/references/mapping/component-mapping.md +35 -20
- package/dist/skills/weixin-to-doubao/references/source-framework/components.md +22 -12
- package/package.json +1 -1
|
@@ -116,6 +116,18 @@ closePage();
|
|
|
116
116
|
|
|
117
117
|
***
|
|
118
118
|
|
|
119
|
+
### exitApp()
|
|
120
|
+
|
|
121
|
+
> **exitApp**(): `Promise`\<`object`\>
|
|
122
|
+
|
|
123
|
+
退去当前所有页面
|
|
124
|
+
|
|
125
|
+
#### Returns
|
|
126
|
+
|
|
127
|
+
`Promise`\<`object`\>
|
|
128
|
+
|
|
129
|
+
***
|
|
130
|
+
|
|
119
131
|
### getAccountInfo()
|
|
120
132
|
|
|
121
133
|
> **getAccountInfo**(`params`?): `Promise`\<[`GetAccountInfoResult`](doubao-apps-sdk-open-api.md#getaccountinforesult)\>
|
|
@@ -352,7 +364,7 @@ Returns a Promise containing privacy setting information
|
|
|
352
364
|
#### Example
|
|
353
365
|
|
|
354
366
|
```typescript
|
|
355
|
-
import { getScreenBrightness } from '@
|
|
367
|
+
import { getScreenBrightness } from '@doubao-apps/framework/api';
|
|
356
368
|
|
|
357
369
|
const result = await getScreenBrightness();
|
|
358
370
|
|
|
@@ -593,7 +605,7 @@ Returns a Promise containing the login credential code
|
|
|
593
605
|
|
|
594
606
|
拨打电话。
|
|
595
607
|
|
|
596
|
-
|
|
608
|
+
入参与宿主应用的拨打电话能力对齐。
|
|
597
609
|
|
|
598
610
|
#### Parameters
|
|
599
611
|
|
|
@@ -647,6 +659,36 @@ await makePhoneCall({ phoneNumber: '10086' });
|
|
|
647
659
|
|
|
648
660
|
***
|
|
649
661
|
|
|
662
|
+
### onKeyboardHeightChange()
|
|
663
|
+
|
|
664
|
+
> **onKeyboardHeightChange**(`handler`): () => `void`
|
|
665
|
+
|
|
666
|
+
监听键盘高度变化事件。
|
|
667
|
+
|
|
668
|
+
#### Parameters
|
|
669
|
+
|
|
670
|
+
• **handler**
|
|
671
|
+
|
|
672
|
+
#### Returns
|
|
673
|
+
|
|
674
|
+
`Function`
|
|
675
|
+
|
|
676
|
+
##### Returns
|
|
677
|
+
|
|
678
|
+
`void`
|
|
679
|
+
|
|
680
|
+
#### Example
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
import { onKeyboardHeightChange } from '@doubao-apps/framework/api';
|
|
684
|
+
|
|
685
|
+
const unsubscribe = onKeyboardHeightChange(({ height }) => {
|
|
686
|
+
console.log('Keyboard height change event:', { height });
|
|
687
|
+
});
|
|
688
|
+
```
|
|
689
|
+
|
|
690
|
+
***
|
|
691
|
+
|
|
650
692
|
### openApp()
|
|
651
693
|
|
|
652
694
|
> **openApp**(`params`): `Promise`\<[`OpenAppResult`](doubao-apps-sdk-open-api.md#openappresult)\>
|
|
@@ -874,6 +916,32 @@ await sendQueryMessage({ content: '订阅消息', type: 'text' })
|
|
|
874
916
|
|
|
875
917
|
***
|
|
876
918
|
|
|
919
|
+
### setClipboardData()
|
|
920
|
+
|
|
921
|
+
> **setClipboardData**(`params`): `Promise`\<`object`\>
|
|
922
|
+
|
|
923
|
+
设置系统剪贴板内容。
|
|
924
|
+
|
|
925
|
+
#### Parameters
|
|
926
|
+
|
|
927
|
+
• **params**: [`SetClipboardDataParams`](doubao-apps-sdk-open-api.md#setclipboarddataparams)
|
|
928
|
+
|
|
929
|
+
#### Returns
|
|
930
|
+
|
|
931
|
+
`Promise`\<`object`\>
|
|
932
|
+
|
|
933
|
+
返回一个 Promise,在剪贴板内容设置成功时解析。
|
|
934
|
+
|
|
935
|
+
#### Example
|
|
936
|
+
|
|
937
|
+
```typescript
|
|
938
|
+
import { setClipboardData } from '@doubao-apps/framework/api';
|
|
939
|
+
|
|
940
|
+
await setClipboardData({ data: 'hello' });
|
|
941
|
+
```
|
|
942
|
+
|
|
943
|
+
***
|
|
944
|
+
|
|
877
945
|
### setStorage()
|
|
878
946
|
|
|
879
947
|
> **setStorage**\<`TData`\>(`params`): `Promise`\<`object`\>
|
|
@@ -1387,6 +1455,18 @@ key 对应的数据
|
|
|
1387
1455
|
|
|
1388
1456
|
***
|
|
1389
1457
|
|
|
1458
|
+
### KeyboardHeightChangeEvent
|
|
1459
|
+
|
|
1460
|
+
#### Properties
|
|
1461
|
+
|
|
1462
|
+
##### height
|
|
1463
|
+
|
|
1464
|
+
> **height**: `number`
|
|
1465
|
+
|
|
1466
|
+
键盘高度,单位 px。
|
|
1467
|
+
|
|
1468
|
+
***
|
|
1469
|
+
|
|
1390
1470
|
### LoginRequest
|
|
1391
1471
|
|
|
1392
1472
|
#### Properties
|
|
@@ -1706,6 +1786,18 @@ HTTP 状态码。
|
|
|
1706
1786
|
|
|
1707
1787
|
***
|
|
1708
1788
|
|
|
1789
|
+
### SetClipboardDataParams
|
|
1790
|
+
|
|
1791
|
+
#### Properties
|
|
1792
|
+
|
|
1793
|
+
##### data
|
|
1794
|
+
|
|
1795
|
+
> **data**: `string`
|
|
1796
|
+
|
|
1797
|
+
需要设置的剪贴板内容
|
|
1798
|
+
|
|
1799
|
+
***
|
|
1800
|
+
|
|
1709
1801
|
### SetStorageParams\<TData\>
|
|
1710
1802
|
|
|
1711
1803
|
#### Type parameters
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: douyin-to-doubao
|
|
3
|
+
description: Migrate Douyin Mini Program (抖音小程序) projects to Doubao Apps SDK (React Lynx). Use when converting TTML/TTSS/JS code, or when users request migration from 抖音小程序 / Douyin Mini Program / tt.* APIs.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 抖音小程序 to Doubao Apps Migration Skill
|
|
7
|
+
|
|
8
|
+
## When to Use
|
|
9
|
+
|
|
10
|
+
- Converting Douyin Mini Program projects to Doubao Apps
|
|
11
|
+
- User mentions "migrate from 抖音小程序", "Douyin to Doubao", "ttml to tsx", "tt.* API migration"
|
|
12
|
+
- Working with `.ttml`, `.ttss`, `Page({})`, `Component({})`, `App({})` patterns
|
|
13
|
+
- Replacing `tt.*` APIs and TTML directives with Doubao Apps patterns
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Core Principles
|
|
18
|
+
|
|
19
|
+
**CRITICAL RULES - MUST FOLLOW:**
|
|
20
|
+
|
|
21
|
+
1. **Preserve Business Logic**: Only change framework APIs and syntax, never modify business logic.
|
|
22
|
+
2. **Plan Before Execute**: Always present migration plan before making changes.
|
|
23
|
+
3. **Official Docs First**: Source-framework judgments must prioritize Douyin official documentation verified on `2026-04-01`.
|
|
24
|
+
4. **Mapping First**: Use mapping docs first; only consult raw framework docs when mapping does not cover a case.
|
|
25
|
+
5. **Incremental Migration**: Migrate and validate file by file.
|
|
26
|
+
6. **Document Gaps**: Record all unsupported or platform-specific features in migration report.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## 官方文档入口(抖音小程序,2026-04-01 校验)
|
|
31
|
+
|
|
32
|
+
以下链接是本 skill 的主要事实依据,遇到边界能力优先回读原文:
|
|
33
|
+
|
|
34
|
+
- 框架概述: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/miniapp-framework/introduction`
|
|
35
|
+
- App / 应用: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/framework/app`
|
|
36
|
+
- Component 构造器: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/custom-component/component-constructor`
|
|
37
|
+
- 组件生命周期: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/custom-component/lifetime`
|
|
38
|
+
- 组件概述: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/component/overview/`
|
|
39
|
+
- TTML 数据绑定: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/miniapp-framework/view/ttml-data-bind`
|
|
40
|
+
- TTML 列表渲染: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/miniapp-framework/view/ttml-list-draw`
|
|
41
|
+
- TTML 事件: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/miniapp-framework/view/ttml-event`
|
|
42
|
+
- 网络连接 / `tt.request`: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/basic-ability/net-connection`
|
|
43
|
+
- 小程序登录 / `tt.login`: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/open-interface/log-in/tt-login`
|
|
44
|
+
- 小程序分享: `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/tutorial/open-capabilities/general-capabilities/share`
|
|
45
|
+
- `tt.authorize`(官方标注“逐步废弃”): `https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/open-interface/authorization/tt-authorize`
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 知识来源速查
|
|
50
|
+
|
|
51
|
+
### 目标框架文档(按需读取)
|
|
52
|
+
|
|
53
|
+
安装路径(`$SKILLS_BASE`,由 Step 0 检测确定):
|
|
54
|
+
|
|
55
|
+
| Agent 环境 | 知识库路径 |
|
|
56
|
+
|------------|-----------|
|
|
57
|
+
| Codex / Cursor / Cline | `.agents/skills/doubao-apps-dev` |
|
|
58
|
+
| Claude Code | `.claude/skills/doubao-apps-dev` |
|
|
59
|
+
|
|
60
|
+
通过以下命令安装:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx @doubao-apps/ai skills add doubao-apps-dev --agent codex
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
| 文档 | 路径 | 用途 |
|
|
67
|
+
|------|------|------|
|
|
68
|
+
| 框架 API 速查 | `$SKILLS_BASE/.ai/reference/framework-api-quick-ref.md` | definePage/defineWidget 等核心 API |
|
|
69
|
+
| 开发规则 | `$SKILLS_BASE/.ai/rules/dos-and-donts.md` | 必须遵守的开发规范 |
|
|
70
|
+
| 组件开发指南 | `$SKILLS_BASE/.ai/guides/component-development.md` | 页面/组件组织方式 |
|
|
71
|
+
| 组件库参考 | `$SKILLS_BASE/.ai/reference/components-quick-ref.md` | UI 组件 API |
|
|
72
|
+
|
|
73
|
+
### 映射文档(迁移核心依据)
|
|
74
|
+
|
|
75
|
+
| 文档 | 路径 |
|
|
76
|
+
|------|------|
|
|
77
|
+
| 核心 API 映射 | `./references/mapping/core-api-mapping.md` |
|
|
78
|
+
| 生命周期映射 | `./references/mapping/lifecycle-mapping.md` |
|
|
79
|
+
| 组件映射 | `./references/mapping/component-mapping.md` |
|
|
80
|
+
| 样式映射 | `./references/mapping/style-mapping.md` |
|
|
81
|
+
| 事件映射 | `./references/mapping/event-mapping.md` |
|
|
82
|
+
|
|
83
|
+
### 源框架文档(按问题读取)
|
|
84
|
+
|
|
85
|
+
| 文档 | 路径 | 何时读取 |
|
|
86
|
+
|------|------|----------|
|
|
87
|
+
| 抖音小程序 API 参考 | `./references/source-framework/api-reference.md` | 识别 `tt.*` API、`Page/Component/App`、登录/分享等开放能力 |
|
|
88
|
+
| 抖音小程序组件参考 | `./references/source-framework/components.md` | 识别 `view`、`scroll-view`、`swiper`、`button`、`input` 等组件语义 |
|
|
89
|
+
|
|
90
|
+
### 代码导入来源
|
|
91
|
+
|
|
92
|
+
| 包名 | 用途 | 示例 |
|
|
93
|
+
|------|------|------|
|
|
94
|
+
| `@doubao-apps/framework` | 框架 API 和 React Hooks | `import { definePage, useState } from '@doubao-apps/framework'` |
|
|
95
|
+
| `@doubao-apps/framework/api` | 端能力 API(替代 `tt.*`) | `import { request, showToast, navigateTo } from '@doubao-apps/framework/api'` |
|
|
96
|
+
| `@doubao-apps/framework/components` | 目标组件库导出;对已支持的小写标签会由 loader 自动注入 import | `import { PickerView, PickerColumn, RadioGroup, Radio } from '@doubao-apps/framework/components'` |
|
|
97
|
+
|
|
98
|
+
> 当前项目已支持直接写小写标签:`<view>`、`<text>`、`<image>`、`<input>`、`<textarea>`、`<scroll-view>`、`<list>`、`<list-item>`、`<button>`、`<switch>`、`<slider>`、`<swiper>`、`<swiper-item>`、`<map>`、`<map-marker>`、`<movable-area>`、`<movable-view>`、`<popup>`、`<radio>`、`<radio-group>`、`<picker-view>`、`<picker-column>`、`<web-view>`、`<svg>`。
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 迁移流程
|
|
103
|
+
|
|
104
|
+
### Step 0: 环境检查
|
|
105
|
+
|
|
106
|
+
**1. 确定知识库路径(`$SKILLS_BASE`)**
|
|
107
|
+
|
|
108
|
+
依次检测以下路径,取第一个存在的作为 `$SKILLS_BASE`:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
ls .agents/skills/doubao-apps-dev/AGENTS.md 2>/dev/null && echo "SKILLS_BASE=.agents/skills/doubao-apps-dev"
|
|
112
|
+
ls .claude/skills/doubao-apps-dev/AGENTS.md 2>/dev/null && echo "SKILLS_BASE=.claude/skills/doubao-apps-dev"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**2. 如未安装,执行安装**
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npx @doubao-apps/ai skills add doubao-apps-dev --agent codex
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**3. 初始化 Doubao Apps 目标项目**
|
|
122
|
+
|
|
123
|
+
询问用户目标项目目录名(默认为源项目目录名加 `-doubao` 后缀),然后创建空项目:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npx @doubao-apps/create <target-dir> --template empty -y
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
创建成功后,将 `<target-dir>` 记录为 `$TARGET_PROJECT_PATH`,后续迁移产物统一输出到该目录。
|
|
130
|
+
|
|
131
|
+
**输出示例**:
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
✅ 环境就绪
|
|
135
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
136
|
+
Agent 环境:Codex
|
|
137
|
+
$SKILLS_BASE:.agents/skills/doubao-apps-dev
|
|
138
|
+
知识库状态:已安装 v0.0.1
|
|
139
|
+
映射文档:5 份就绪
|
|
140
|
+
目标项目:./my-douyin-miniapp-doubao(已创建)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Step 1: 分析源项目
|
|
146
|
+
|
|
147
|
+
扫描抖音小程序项目,识别:
|
|
148
|
+
|
|
149
|
+
- `.ttml` 文件数量和页面/组件分布
|
|
150
|
+
- 使用的 `tt.*` API 清单
|
|
151
|
+
- `tt:` 指令使用情况(`tt:if` / `tt:for` / `tt:key`)
|
|
152
|
+
- 使用的组件列表(`view`、`scroll-view`、`swiper`、`navigator`、`button` 等)
|
|
153
|
+
- `app.json` 与各页面 `.json` 的页面配置、路由、`usingComponents`
|
|
154
|
+
- 自定义组件及其 `properties` / `pageLifetimes` / 事件依赖
|
|
155
|
+
- 平台专有能力:登录、分享、挂载到抖音视频/直播、`open-type`、授权链路
|
|
156
|
+
|
|
157
|
+
**输出示例**:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
📊 项目分析报告
|
|
161
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
162
|
+
文件数量:18 个页面/组件
|
|
163
|
+
└─ 页面(pages/):12 个
|
|
164
|
+
└─ 组件(components/):6 个
|
|
165
|
+
|
|
166
|
+
使用的 tt.* API:
|
|
167
|
+
✅ 有直接迁移路径:tt.request, tt.showToast, tt.navigateTo, tt.setStorageSync (11 个)
|
|
168
|
+
⚠️ 需人工决策:tt.login, 分享挂载能力, button open-type (4 个)
|
|
169
|
+
|
|
170
|
+
TTML 指令:
|
|
171
|
+
✅ 常规:tt:if, tt:for, tt:key
|
|
172
|
+
⚠️ 需重写:bind:tap.capture, bind:tap.stop.prevent
|
|
173
|
+
|
|
174
|
+
组件:
|
|
175
|
+
✅ 有映射:view, text, image, scroll-view, button, input, swiper, movable-area, radio-group, picker-view (10 个)
|
|
176
|
+
⚠️ 需适配:navigator, picker, checkbox-group (3 个)
|
|
177
|
+
❌ 平台强绑定:video 发布/直播挂载入口(2 个)
|
|
178
|
+
|
|
179
|
+
复杂度评估:中高
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### Step 2: 读取映射文档
|
|
185
|
+
|
|
186
|
+
按以下顺序读取,建立转换规则索引:
|
|
187
|
+
|
|
188
|
+
1. `./references/mapping/core-api-mapping.md`
|
|
189
|
+
2. `./references/mapping/lifecycle-mapping.md`
|
|
190
|
+
3. `./references/mapping/component-mapping.md`
|
|
191
|
+
4. `./references/mapping/style-mapping.md`
|
|
192
|
+
5. `./references/mapping/event-mapping.md`
|
|
193
|
+
|
|
194
|
+
遇到未覆盖场景时,再回读源框架文档:
|
|
195
|
+
|
|
196
|
+
1. `./references/source-framework/api-reference.md`
|
|
197
|
+
2. `./references/source-framework/components.md`
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### Step 3: 生成迁移计划
|
|
202
|
+
|
|
203
|
+
基于项目分析和映射规则,生成迁移计划并**展示给用户确认**:
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
📋 迁移计划
|
|
207
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
208
|
+
迁移顺序(共 18 个文件):
|
|
209
|
+
[1] pages/index/index → 简单,纯展示页
|
|
210
|
+
[2] pages/feed/detail → 中等,含 tt.request / 分享
|
|
211
|
+
[3] components/banner-card → 中等,含 swiper
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
风险点:
|
|
215
|
+
⚠️ tt.login 需要重接服务端登录态
|
|
216
|
+
⚠️ button open-type="share" / 视频挂载能力无机械等价物
|
|
217
|
+
⚠️ pageLifetimes.resize 需要上提到页面容器重写
|
|
218
|
+
|
|
219
|
+
是否开始迁移?(y/n)
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
### Step 4: 执行迁移
|
|
225
|
+
|
|
226
|
+
#### 4.1 文件转换规则
|
|
227
|
+
|
|
228
|
+
抖音小程序每个页面/组件通常由 4 个文件组成,迁移后统一收敛为 Doubao Apps 的 `index.tsx` + `index.scss`:
|
|
229
|
+
|
|
230
|
+
| 抖音小程序 | Doubao Apps | 说明 |
|
|
231
|
+
|-----------|-------------|------|
|
|
232
|
+
| `page.ttml` | `index.tsx` JSX 部分 | 模板转 TSX |
|
|
233
|
+
| `page.ttss` | `index.scss` | 样式尽量保留 class 语义 |
|
|
234
|
+
| `page.js` / `page.ts` | `index.tsx` 组件逻辑 | `Page({})` / `Component({})` 转 `definePage({})` 或 FC |
|
|
235
|
+
| `page.json` | 合并到页面定义/路由配置 | 页面配置不再逐文件保留 |
|
|
236
|
+
|
|
237
|
+
> **⚠️ 命名约束**:页面/组件目录下的入口文件必须命名为 **`index.tsx`**,样式文件为 **`index.scss`**。
|
|
238
|
+
|
|
239
|
+
#### 4.2 单文件转换步骤(每个页面/组件)
|
|
240
|
+
|
|
241
|
+
1. **依赖更新**:移除抖音小程序专属依赖,添加 `@doubao-apps/framework`
|
|
242
|
+
2. **import 语句转换**:`tt.*` → `@doubao-apps/framework/api`
|
|
243
|
+
3. **页面/组件定义方式**:`Page({})` / `Component({})` → `definePage({})` / `FC<Props>`
|
|
244
|
+
4. **状态管理**:`data` + `setData` → `useState` / `useMemo` / `useEffect`
|
|
245
|
+
5. **生命周期转换**:见 `lifecycle-mapping.md`
|
|
246
|
+
6. **TTML 模板转 TSX**:见 `component-mapping.md`
|
|
247
|
+
7. **TTSS 样式转 `index.scss`**:见 `style-mapping.md`
|
|
248
|
+
8. **事件绑定**:见 `event-mapping.md`
|
|
249
|
+
9. **平台能力拆分**:登录、分享、抖音视频/直播挂载能力单独标记
|
|
250
|
+
|
|
251
|
+
#### 4.3 转换策略(优先级从高到低)
|
|
252
|
+
|
|
253
|
+
```text
|
|
254
|
+
映射文档 → 官方源文档 → 目标框架文档 → AI 推断 → 询问用户
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
### Step 5: 迁移摘要
|
|
260
|
+
|
|
261
|
+
输出本次迁移的执行结果:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
📋 迁移摘要
|
|
265
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
266
|
+
已迁移:16/18 文件
|
|
267
|
+
└─ 页面:11 个
|
|
268
|
+
└─ 组件:5 个
|
|
269
|
+
|
|
270
|
+
跳过(平台强绑定):
|
|
271
|
+
- pages/share-mount/index:依赖抖音分享/挂载链路
|
|
272
|
+
- components/live-entry/index:依赖直播挂载能力
|
|
273
|
+
|
|
274
|
+
需人工处理:
|
|
275
|
+
- tt.login × 2 处:需重建服务端 code2session 登录链路
|
|
276
|
+
- button open-type × 3 处:需按业务目标改成 Doubao 原生交互
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
### Step 6: 质量门禁(Quality Gate)
|
|
282
|
+
|
|
283
|
+
迁移完成后,必须执行同级 skill:
|
|
284
|
+
|
|
285
|
+
```text
|
|
286
|
+
<当前 skill 同级目录>/quality-gate/SKILL.md
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
最低要求:
|
|
290
|
+
|
|
291
|
+
- TypeScript 无报错
|
|
292
|
+
- 页面可渲染
|
|
293
|
+
- 核心路由可跳转
|
|
294
|
+
- 网络请求与状态更新正常
|
|
295
|
+
- 样式无明显结构性错位
|
|
296
|
+
- 所有平台能力缺口都有迁移备注
|
|
297
|
+
|
|
298
|
+
---
|
|
299
|
+
|
|
300
|
+
## 特别注意事项
|
|
301
|
+
|
|
302
|
+
### 1. 抖音小程序页面可能用 `Component()` 构造
|
|
303
|
+
|
|
304
|
+
官方文档明确支持“使用 `Component` 构造器构造页面”。扫描时如果发现页面不是 `Page({})` 而是 `Component({})`,不要误判成普通组件,仍按页面迁移到 `definePage({})`。
|
|
305
|
+
|
|
306
|
+
### 2. `tt.authorize` 不应被新代码直接平移
|
|
307
|
+
|
|
308
|
+
官方文档已标记该 API “逐步废弃,后续不再维护”。遇到旧项目使用 `tt.authorize` 时,优先按具体能力重接,而不是照搬。
|
|
309
|
+
|
|
310
|
+
### 3. 分享、视频挂载、直播挂载不是普通 UI 迁移
|
|
311
|
+
|
|
312
|
+
这些能力依赖抖音宿主链路,不应简单替换为一个按钮或导航调用。必须在迁移报告里单列。
|
|
313
|
+
|
|
314
|
+
### 4. 事件语法需要区分老写法和新写法
|
|
315
|
+
|
|
316
|
+
抖音小程序同时存在:
|
|
317
|
+
|
|
318
|
+
- 老写法:`bindtap` / `catchtap` / `capture-bind:touchstart`
|
|
319
|
+
- 官方新写法:`bind:tap` / `bind:tap.capture` / `bind:tap.stop.prevent`
|
|
320
|
+
|
|
321
|
+
迁移时统一转换为 TSX 函数引用和显式事件语义。
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
325
|
+
## 输出要求
|
|
326
|
+
|
|
327
|
+
迁移结束时必须给出:
|
|
328
|
+
|
|
329
|
+
1. 项目分析报告
|
|
330
|
+
2. 用户确认过的迁移计划
|
|
331
|
+
3. 迁移摘要
|
|
332
|
+
4. 未完成项 / 平台能力缺口列表
|
|
333
|
+
5. 后续质量门禁执行建议
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# 抖音小程序 → Doubao Apps 迁移检查清单
|
|
2
|
+
|
|
3
|
+
> 对每个迁移的页面/组件,逐项执行本清单。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 前置准备
|
|
8
|
+
|
|
9
|
+
- [ ] 备份原始抖音小程序项目
|
|
10
|
+
- [ ] 安装 Doubao Apps 知识库:`npx @doubao-apps/ai skills add doubao-apps-dev --agent codex`
|
|
11
|
+
- [ ] 梳理项目页面列表(来自 `app.json` 的 `pages` 字段)
|
|
12
|
+
- [ ] 梳理自定义组件列表与 `usingComponents`
|
|
13
|
+
- [ ] 识别所有 `tt.*` API 调用,标记平台强绑定能力
|
|
14
|
+
- [ ] 识别所有 `open-type`、分享、视频挂载、直播挂载入口
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 依赖处理
|
|
19
|
+
|
|
20
|
+
- [ ] 移除抖音小程序专属依赖或 runtime
|
|
21
|
+
- [ ] 添加 `@doubao-apps/framework`
|
|
22
|
+
- [ ] 更新 `tsconfig.json`
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## 逐文件迁移清单
|
|
27
|
+
|
|
28
|
+
对每个 `.ttml` + `.ttss` + `.js/.ts` + `.json` 文件组,执行以下步骤:
|
|
29
|
+
|
|
30
|
+
### 1. Import 语句转换
|
|
31
|
+
|
|
32
|
+
- [ ] 移除全局 `tt` 对象直接调用
|
|
33
|
+
- [ ] 添加 `import { ... } from '@doubao-apps/framework'`
|
|
34
|
+
- [ ] 添加 `import { ... } from '@doubao-apps/framework/api'`
|
|
35
|
+
- [ ] UI 组件直接使用小写标签,不要手写导入组件库
|
|
36
|
+
|
|
37
|
+
### 2. 页面 / 组件定义转换
|
|
38
|
+
|
|
39
|
+
- [ ] `Page({})` → `definePage({ ..., render() { return <PageComponent /> } })`
|
|
40
|
+
- [ ] 页面若用 `Component({})` 构造,也要落为 `definePage({})`
|
|
41
|
+
- [ ] `Component({ properties, methods })` → `FC<Props>`
|
|
42
|
+
- [ ] `App({})` → `defineApp({...})`
|
|
43
|
+
- [ ] `.json` 页面配置合并到目标工程结构
|
|
44
|
+
|
|
45
|
+
### 3. 状态管理转换
|
|
46
|
+
|
|
47
|
+
- [ ] `data: { foo: val }` → `const [foo, setFoo] = useState(val)`
|
|
48
|
+
- [ ] `this.setData({ foo: val })` → `setFoo(val)`
|
|
49
|
+
- [ ] `this.setData({ 'arr[0].key': val })` → 展开更新或 reducer
|
|
50
|
+
- [ ] `this.data.foo` → 直接使用变量 `foo`
|
|
51
|
+
- [ ] `this.properties.foo` → `props.foo`
|
|
52
|
+
|
|
53
|
+
### 4. 生命周期转换
|
|
54
|
+
|
|
55
|
+
- [ ] Page `onLoad(options)` → 不假设 `definePage` 存在同名钩子;页面输入改由 `getViewData()/getViewContext()` 或页面容器显式注入
|
|
56
|
+
- [ ] Page `onShow / onHide` → `definePage.onShow/onHide`
|
|
57
|
+
- [ ] Page `onReady` → `definePage.onMounted` 或组件内 `useEffect`
|
|
58
|
+
- [ ] Page `onUnload` → `definePage.onDestroy`
|
|
59
|
+
- [ ] Page `onPullDownRefresh / onReachBottom / onPageScroll` → 按页面容器或 `scroll-view` 事件重写,不假设存在同名页面钩子
|
|
60
|
+
- [ ] Component `attached / ready` → `useEffect(() => {...}, [])`
|
|
61
|
+
- [ ] Component `detached` → `useEffect(() => () => cleanup(), [])`
|
|
62
|
+
- [ ] `pageLifetimes.show/hide/resize` 上提到页面容器
|
|
63
|
+
|
|
64
|
+
### 5. TTML 模板转 TSX
|
|
65
|
+
|
|
66
|
+
- [ ] `{{expression}}` → `{expression}`
|
|
67
|
+
- [ ] `tt:if="{{cond}}"` → 条件表达式
|
|
68
|
+
- [ ] `tt:for="{{list}}" tt:key="id"` → `list.map(...)`
|
|
69
|
+
- [ ] `<block>` → `<>...</>` 或直接移除
|
|
70
|
+
- [ ] 文本内容包裹在 `<text>` 中
|
|
71
|
+
- [ ] `<navigator url="...">` → 显式路由 API
|
|
72
|
+
|
|
73
|
+
### 6. TTSS 样式转 `index.scss`
|
|
74
|
+
|
|
75
|
+
- [ ] `page.ttss` → `index.scss`
|
|
76
|
+
- [ ] `class="xxx"` → `className="xxx"`
|
|
77
|
+
- [ ] 保留可复用 class 语义,不要无脑改成内联 style
|
|
78
|
+
- [ ] `rpx` / `px` / 百分比单位按 Doubao 样式能力核对
|
|
79
|
+
- [ ] 对不兼容选择器和继承样式做扁平化处理
|
|
80
|
+
|
|
81
|
+
### 7. 事件绑定转换
|
|
82
|
+
|
|
83
|
+
- [ ] `bindtap` / `bind:tap` → `onClick={handleTap}`
|
|
84
|
+
- [ ] `catchtap` / `catch:tap` / `bind:tap.stop` → `onCatchTap={handleTap}`
|
|
85
|
+
- [ ] `capture-bind:*` / `bind:*.capture` → 视情况重构事件流
|
|
86
|
+
- [ ] `bind:input` → `onInput`
|
|
87
|
+
- [ ] `bind:tap.prevent` → 明确改写默认行为,不做机械替换
|
|
88
|
+
- [ ] `data-* + dataset` → 优先改为闭包传值
|
|
89
|
+
|
|
90
|
+
### 8. `tt.*` API 转换
|
|
91
|
+
|
|
92
|
+
- [ ] `tt.request(...)` → `request(...)`
|
|
93
|
+
- [ ] `tt.navigateTo/Back/RedirectTo(...)` → 对应路由 API
|
|
94
|
+
- [ ] `tt.showToast(...)` → `showToast({ message, ... })`(注意 `title` 需改成 `message`)
|
|
95
|
+
- [ ] `tt.showLoading/hideLoading/showModal(...)` → 先核对当前项目是否真的暴露对应 API,再决定是否迁移
|
|
96
|
+
- [ ] `tt.getStorageSync/setStorageSync(...)` → 对应存储 API
|
|
97
|
+
- [ ] `tt.login(...)` → 标记为服务端登录链路改造项
|
|
98
|
+
- [ ] `tt.authorize(...)` → 标记为废弃能力重构项
|
|
99
|
+
|
|
100
|
+
### 9. 组件替换
|
|
101
|
+
|
|
102
|
+
- [ ] `view / text / image / scroll-view` → 对应 Doubao 标签
|
|
103
|
+
- [ ] `swiper / swiper-item` → 直接使用小写 `<swiper>` / `<swiper-item>` 标签
|
|
104
|
+
- [ ] `switch / slider / picker / radio / checkbox` → 直接使用小写标签;如目标标签能力不足,再按业务补封装
|
|
105
|
+
- [ ] `button open-type=*` → 不机械迁移,按业务重写
|
|
106
|
+
- [ ] `navigator` → 用路由 API 重写
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 验证步骤
|
|
111
|
+
|
|
112
|
+
- [ ] TypeScript 编译无报错:`npx tsc --noEmit`
|
|
113
|
+
- [ ] 构建成功:`pnpm run build`
|
|
114
|
+
- [ ] 所有页面可正常渲染
|
|
115
|
+
- [ ] 事件触发正常
|
|
116
|
+
- [ ] 状态更新正常
|
|
117
|
+
- [ ] 网络请求正常
|
|
118
|
+
- [ ] 路由跳转正常
|
|
119
|
+
- [ ] 样式结构正确
|
|
120
|
+
- [ ] 平台强绑定能力均已记录
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 平台能力缺口记录
|
|
125
|
+
|
|
126
|
+
| 功能 | 原因 | 处理状态 |
|
|
127
|
+
|------|------|---------|
|
|
128
|
+
| | | |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 迁移报告模板
|
|
133
|
+
|
|
134
|
+
```text
|
|
135
|
+
迁移完成时间:YYYY-MM-DD
|
|
136
|
+
迁移文件数量:____ 个(页面 ____ + 组件 ____)
|
|
137
|
+
完成率:____/____(____%)
|
|
138
|
+
|
|
139
|
+
未完成项:
|
|
140
|
+
- [文件] [原因]
|
|
141
|
+
|
|
142
|
+
平台能力缺口:
|
|
143
|
+
- [能力名称] × [调用次数]:[处理建议]
|
|
144
|
+
```
|