@ohos-cpf/3rdloop 0.0.4 → 0.0.5

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.
Files changed (43) hide show
  1. package/README.md +119 -128
  2. package/lib/cli.js +25 -0
  3. package/lib/serve.js +268 -0
  4. package/lib/update.js +46 -6
  5. package/lib/web-ext.js +454 -0
  6. package/lib/web.js +664 -0
  7. package/package.json +2 -1
  8. package/vendor/Server/Skills/arkts-code-use/SKILL.md +270 -0
  9. package/vendor/Server/Skills/arkts-code-use/assets/TEMPLATES.md +367 -0
  10. package/vendor/Server/Skills/arkts-code-use/references/API_VERIFICATION.md +144 -0
  11. package/vendor/Server/Skills/arkts-code-use/references/ARKTS_RULES.md +240 -0
  12. package/vendor/Server/Skills/arkts-code-use/references/CODE_PATTERNS.md +431 -0
  13. package/vendor/Server/Skills/arkts-code-use/references/SYNTAX_CHECK_GUIDE.md +164 -0
  14. package/vendor/Server/Skills/arkts-code-use/scripts/verify-arkts.cjs +428 -0
  15. package/vendor/Server/Skills/gitcode-repo-fork/SKILL.md +310 -0
  16. package/vendor/Server/Skills/gitcode-repo-fork/assets/FORK_REPORT_TEMPLATE.md +113 -0
  17. package/vendor/Server/Skills/gitcode-repo-fork/references/FORK_DECISION_GUIDE.md +124 -0
  18. package/vendor/Server/Skills/gitcode-repo-fork/references/GITCODE_FORK_API.md +95 -0
  19. package/vendor/Server/Skills/gitcode-repo-fork/scripts/gitcode-fork.cjs +285 -0
  20. package/vendor/VERSION +3 -3
  21. package/web/css/arktslibrarycheck.css +322 -0
  22. package/web/css/codecheck.css +464 -0
  23. package/web/css/flutterlibrarycheck.css +322 -0
  24. package/web/css/knowledge.css +332 -0
  25. package/web/css/loop.css +578 -0
  26. package/web/css/md-reader.css +240 -0
  27. package/web/css/rnlibrarycheck.css +322 -0
  28. package/web/css/theme.css +702 -0
  29. package/web/index.html +713 -0
  30. package/web/js/arktslibrarycheck.js +1413 -0
  31. package/web/js/codecheck.js +1039 -0
  32. package/web/js/flutterlibrarycheck.js +1364 -0
  33. package/web/js/health.js +69 -0
  34. package/web/js/knowledge.js +358 -0
  35. package/web/js/loop.js +1102 -0
  36. package/web/js/md-reader.js +435 -0
  37. package/web/js/navigation.js +238 -0
  38. package/web/js/rnlibrarycheck.js +1378 -0
  39. package/web/js/stats.js +110 -0
  40. package/web/js/theme.js +46 -0
  41. package/web/js/utils.js +228 -0
  42. package/web/knowledge.html +146 -0
  43. package/web/loop.html +219 -0
@@ -0,0 +1,431 @@
1
+ # ArkTS 代码模式
2
+
3
+ > 编写鸿蒙原生 ArkTS 代码时的标准实现模式:异步编程、并发、错误处理、事件、权限、资源生命周期、UI 状态管理。所有模式均已通过 ArkTS 严格模式编译验证。
4
+
5
+ ---
6
+
7
+ ## 一、异步编程模式
8
+
9
+ ### 1.1 Promise + async/await(默认选择)
10
+
11
+ ```typescript
12
+ import fs from '@ohos.file.fs';
13
+ import hilog from '@ohos.hilog';
14
+
15
+ const DOMAIN: number = 0x0001;
16
+ const TAG: string = 'MyApp_Async';
17
+
18
+ /** 将回调式 API 封装为 Promise */
19
+ function readTextAsync(filePath: string): Promise<string> {
20
+ return new Promise<string>((resolve: (value: string) => void,
21
+ reject: (reason: Error) => void) => {
22
+ fs.readText(filePath, (err: Error, data: string) => {
23
+ if (err) {
24
+ reject(err instanceof Error ? err : new Error(String(err)));
25
+ return;
26
+ }
27
+ resolve(data);
28
+ });
29
+ });
30
+ }
31
+
32
+ /** 调用方:async/await + try/catch/finally */
33
+ async function processFile(filePath: string): Promise<string> {
34
+ try {
35
+ const content: string = await readTextAsync(filePath);
36
+ hilog.info(DOMAIN, TAG, 'read ok, length=%{public}d', content.length);
37
+ return content;
38
+ } catch (e) {
39
+ hilog.error(DOMAIN, TAG, 'read failed: %{public}s', (e as Error).message);
40
+ throw e instanceof Error ? e : new Error(String(e));
41
+ }
42
+ }
43
+ ```
44
+
45
+ ### 1.2 超时控制(Promise.race)
46
+
47
+ ```typescript
48
+ function withTimeout<T>(task: Promise<T>, timeoutMs: number): Promise<T> {
49
+ const timer: Promise<never> = new Promise<never>(
50
+ (_resolve: (value: never) => void, reject: (reason: Error) => void) => {
51
+ setTimeout(() => {
52
+ reject(new Error(`timeout after ${timeoutMs}ms`));
53
+ }, timeoutMs);
54
+ });
55
+ return Promise.race<T>([task, timer]);
56
+ }
57
+ ```
58
+
59
+ ---
60
+
61
+ ## 二、并发模式(taskpool / worker)
62
+
63
+ > 阻塞 IO、大量计算禁止在主线程执行。优先 taskpool(轻量任务池),长生命周期后台线程用 worker。
64
+
65
+ ### 2.1 taskpool 耗时计算
66
+
67
+ ```typescript
68
+ import taskpool from '@ohos.taskpool';
69
+
70
+ // @Concurrent 函数必须是独立函数,不能捕获外部变量(可序列化参数传入)
71
+ @Concurrent
72
+ function computeChecksum(input: number[]): number {
73
+ let sum: number = 0;
74
+ for (const value of input) {
75
+ sum += value * 31;
76
+ }
77
+ return sum;
78
+ }
79
+
80
+ async function runInBackground(input: number[]): Promise<number> {
81
+ const task: taskpool.Task = new taskpool.Task(computeChecksum, input);
82
+ return await taskpool.execute(task) as number;
83
+ }
84
+ ```
85
+
86
+ ### 2.2 worker 生命周期(必须 terminate)
87
+
88
+ ```typescript
89
+ import worker from '@ohos.worker';
90
+
91
+ class WorkerHost {
92
+ private threadWorker: worker.ThreadWorker | null = null;
93
+
94
+ start(): void {
95
+ // 脚本路径相对模块 src/main/ets
96
+ this.threadWorker = new worker.ThreadWorker('entry/ets/workers/MyWorker.ets');
97
+ this.threadWorker.onmessage = (event: MessageEvents): void => {
98
+ // 处理子线程结果
99
+ };
100
+ this.threadWorker.postMessage({ type: 'start' });
101
+ }
102
+
103
+ /** 必须在确定生命周期节点调用,防止线程泄露 */
104
+ stop(): void {
105
+ if (this.threadWorker !== null) {
106
+ this.threadWorker.terminate();
107
+ this.threadWorker = null;
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 三、错误处理模式
116
+
117
+ ### 3.1 BusinessError(系统 API 标准错误)
118
+
119
+ ```typescript
120
+ import { BusinessError } from '@ohos.base';
121
+
122
+ async function callSystemApi(): Promise<void> {
123
+ try {
124
+ // await someSystemApi();
125
+ } catch (error) {
126
+ // 系统 API 错误统一转型为 BusinessError 读取 code
127
+ const err: BusinessError = error as BusinessError;
128
+ hilog.error(0x0001, 'MyApp', 'code=%{public}d, msg=%{public}s', err.code, err.message);
129
+ throw err instanceof Error ? err : new Error(String(err));
130
+ }
131
+ }
132
+ ```
133
+
134
+ ### 3.2 参数防御性校验
135
+
136
+ ```typescript
137
+ class ValidationError extends Error {
138
+ constructor(message: string) {
139
+ super(message);
140
+ this.name = 'ValidationError';
141
+ }
142
+ }
143
+
144
+ function validateInput(value: string | null | undefined, fieldName: string,
145
+ maxLen: number = 256): string {
146
+ if (value === null || value === undefined || value.length === 0) {
147
+ throw new ValidationError(`${fieldName} must not be empty`);
148
+ }
149
+ if (value.length > maxLen) {
150
+ throw new ValidationError(`${fieldName} exceeds max length ${maxLen}`);
151
+ }
152
+ return value;
153
+ }
154
+ ```
155
+
156
+ ### 3.3 统一 Result 类型(避免异常控制流蔓延)
157
+
158
+ ```typescript
159
+ export interface Result<T> {
160
+ success: boolean;
161
+ value?: T;
162
+ error?: string;
163
+ }
164
+
165
+ export class Ok<T> implements Result<T> {
166
+ success: boolean = true;
167
+ constructor(public value: T) {}
168
+ }
169
+
170
+ export class Fail<T> implements Result<T> {
171
+ success: boolean = false;
172
+ constructor(public error: string) {}
173
+ }
174
+ ```
175
+
176
+ ---
177
+
178
+ ## 四、事件模式(emitter)
179
+
180
+ ```typescript
181
+ import emitter from '@ohos.events.emitter';
182
+
183
+ // 事件常量集中定义
184
+ export const enum AppEvent {
185
+ DATA_UPDATED = 1001,
186
+ SYNC_FAILED = 1002,
187
+ }
188
+
189
+ class EventBus {
190
+ private static subscriptionCount: number = 0;
191
+
192
+ static subscribe(eventId: number, callback: (data: emitter.EventData) => void): void {
193
+ emitter.on({ eventId: eventId }, callback);
194
+ EventBus.subscriptionCount += 1;
195
+ }
196
+
197
+ static emit(eventId: number, data: Record<string, Object>): void {
198
+ emitter.emit({ eventId: eventId }, { data: data });
199
+ }
200
+
201
+ /** 取消订阅必须与 on 配对 */
202
+ static unsubscribe(eventId: number): void {
203
+ emitter.off(eventId);
204
+ }
205
+ }
206
+ ```
207
+
208
+ ---
209
+
210
+ ## 五、权限申请模式
211
+
212
+ ```typescript
213
+ import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
214
+ import { common } from '@kit.AbilityKit';
215
+
216
+ async function requestPermissions(context: common.UIAbilityContext,
217
+ permissions: Permissions[]): Promise<boolean> {
218
+ const atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
219
+ const result: abilityAccessCtrl.PermissionRequestResult =
220
+ await atManager.requestPermissionsFromUser(context, permissions);
221
+ return result.authResults.every((status: number) =>
222
+ status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED);
223
+ }
224
+ ```
225
+
226
+ > normal 级权限仅声明即生效;user_grant 级权限须声明 + 运行时申请两步缺一不可。
227
+
228
+ ---
229
+
230
+ ## 六、资源生命周期管理(防泄露)
231
+
232
+ > **规则**:凡是 `create/open/on/connect` 获取的资源,必须存在对称的 `destroy/close/off/disconnect` 释放路径,置于 `try/finally` 或组件销毁回调中。
233
+
234
+ | 资源 | 获取 | 释放 | 位置 |
235
+ |------|------|------|------|
236
+ | HTTP 连接 | `http.createHttp()` | `httpRequest.destroy()` | `try/finally` |
237
+ | 文件句柄 | `fs.openSync()` | `fs.closeSync(fd)` | `try/finally` |
238
+ | RDB 存储 | `getRdbStore()` | `close()` | 模块卸载 |
239
+ | Worker | `new ThreadWorker()` | `terminate()` | 任务完成/销毁 |
240
+ | Timer | `setInterval()` | `clearInterval(id)` | `aboutToDisappear` |
241
+ | emitter 订阅 | `emitter.on()` | `emitter.off(id)` | `aboutToDisappear` |
242
+ | 传感器 | `sensor.on()` | `sensor.off(type)` | 页面隐藏/销毁 |
243
+ | AVPlayer | `createAVPlayer()` | `release()` | 播放结束/销毁 |
244
+
245
+ ### 6.1 HTTP 请求标准范式(最常见泄露点)
246
+
247
+ ```typescript
248
+ import { http } from '@kit.NetworkKit';
249
+
250
+ const MAX_RESPONSE_BYTES: number = 5 * 1024 * 1024;
251
+
252
+ async function httpGet(url: string): Promise<string> {
253
+ const httpRequest: http.HttpRequest = http.createHttp();
254
+ try {
255
+ const response: http.HttpResponse = await httpRequest.request(url, {
256
+ method: http.RequestMethod.GET,
257
+ connectTimeout: 10_000,
258
+ readTimeout: 15_000,
259
+ expectMaxDuration: 20_000,
260
+ });
261
+ if (typeof response.result !== 'string') {
262
+ throw new Error('unexpected response type');
263
+ }
264
+ if (response.result.length > MAX_RESPONSE_BYTES) {
265
+ throw new Error(`response too large: ${response.result.length}`);
266
+ }
267
+ return response.result;
268
+ } finally {
269
+ // ✅ 成功失败均释放
270
+ httpRequest.destroy();
271
+ }
272
+ }
273
+ ```
274
+
275
+ ### 6.2 文件读写标准范式
276
+
277
+ ```typescript
278
+ import fs from '@ohos.file.fs';
279
+
280
+ function readFileSafely(filePath: string): string {
281
+ let fd: number = -1;
282
+ try {
283
+ const file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
284
+ fd = file.fd;
285
+ const stat: fs.Stat = fs.statSync(filePath);
286
+ const buffer: ArrayBuffer = new ArrayBuffer(stat.size);
287
+ fs.readSync(fd, buffer);
288
+ return String.fromCharCode(...new Uint8Array(buffer));
289
+ } finally {
290
+ if (fd >= 0) {
291
+ fs.closeSync(fd);
292
+ }
293
+ }
294
+ }
295
+ ```
296
+
297
+ ### 6.3 组件内订阅/Timer 清理
298
+
299
+ ```typescript
300
+ @Component
301
+ struct PollingComponent {
302
+ @State message: string = '';
303
+ private timerId: number = -1;
304
+
305
+ aboutToAppear(): void {
306
+ this.timerId = setInterval(() => {
307
+ this.message = `tick ${Date.now()}`;
308
+ }, 1000);
309
+ }
310
+
311
+ aboutToDisappear(): void {
312
+ if (this.timerId >= 0) {
313
+ clearInterval(this.timerId);
314
+ this.timerId = -1;
315
+ }
316
+ }
317
+
318
+ build() {
319
+ Text(this.message)
320
+ }
321
+ }
322
+ ```
323
+
324
+ ---
325
+
326
+ ## 七、UI 状态管理模式
327
+
328
+ ### 7.1 父子组件通信
329
+
330
+ ```typescript
331
+ // 子组件:单向输入 @Prop,双向绑定 @Link
332
+ @Component
333
+ struct CounterCard {
334
+ @Prop title: string = '';
335
+ @Link count: number;
336
+
337
+ build() {
338
+ Column({ space: 8 }) {
339
+ Text(this.title)
340
+ .fontSize(16)
341
+ Text(`count: ${this.count}`)
342
+ .fontSize(20)
343
+ Button('+1')
344
+ .onClick(() => {
345
+ this.count += 1;
346
+ })
347
+ }
348
+ .padding(12)
349
+ }
350
+ }
351
+
352
+ @Entry
353
+ @Component
354
+ struct Index {
355
+ @State count: number = 0;
356
+
357
+ build() {
358
+ Column({ space: 12 }) {
359
+ CounterCard({ title: 'demo', count: $count }) // @Link 用 $ 传引用
360
+ }
361
+ }
362
+ }
363
+ ```
364
+
365
+ ### 7.2 @Provide/@Consume 跨层级
366
+
367
+ ```typescript
368
+ // 祖先组件
369
+ @Entry
370
+ @Component
371
+ struct GrandParent {
372
+ @Provide themeColor: string = '#007DFF';
373
+
374
+ build() { /* 包含后代组件 */ }
375
+ }
376
+
377
+ // 任意后代组件(无需逐层传递)
378
+ @Component
379
+ struct DeepChild {
380
+ @Consume themeColor: string;
381
+
382
+ build() {
383
+ Text('themed').fontColor(this.themeColor)
384
+ }
385
+ }
386
+ ```
387
+
388
+ ### 7.3 @Builder 复用 + @BuilderParam 插槽
389
+
390
+ ```typescript
391
+ @Builder
392
+ function LoadingView(text: string) {
393
+ Column({ space: 8 }) {
394
+ LoadingProgress().width(48).height(48)
395
+ Text(text).fontSize(14)
396
+ }
397
+ .width('100%')
398
+ .justifyContent(FlexAlign.Center)
399
+ }
400
+ ```
401
+
402
+ ---
403
+
404
+ ## 八、兼容性守卫模式
405
+
406
+ ```typescript
407
+ import deviceInfo from '@ohos.deviceInfo';
408
+
409
+ // 硬件能力检测:调用蓝牙/NFC/摄像头前必须
410
+ function ensureBluetooth(): boolean {
411
+ return canIUse('SystemCapability.Communication.Bluetooth.Core');
412
+ }
413
+
414
+ // API Level 守卫:使用 since 高于目标版本的接口前必须
415
+ function getSdkApiLevel(): number {
416
+ return deviceInfo.sdkApiVersion;
417
+ }
418
+ ```
419
+
420
+ ---
421
+
422
+ ## 九、典型平台陷阱速查
423
+
424
+ | 陷阱 | 正确做法 |
425
+ |------|---------|
426
+ | 沙箱路径 | 用 `context.filesDir` / `context.cacheDir`;禁止硬编码 `/data/local/tmp` |
427
+ | rawfile 资源 | 不可直接路径访问;用 `resourceManager.getRawFileContentSync()` / `getRawFdSync()` |
428
+ | `file://` 前缀 | 拼接为 `file://` + 绝对路径(两斜杠),媒体 URL 不用三斜杠 |
429
+ | fs.writeSync 传 Uint8Array | 必须传 `uint8array.buffer`(ArrayBuffer) |
430
+ | 高频 hilog.debug | 禁止每帧/每秒多次打印,影响性能 |
431
+ | 阻塞主线程 | `Thread.sleep` 类同步等待不存在;用 `await new Promise` + setTimeout 或 taskpool |
@@ -0,0 +1,164 @@
1
+ # 语法验证指南(deveco-cli)
2
+
3
+ > 生成的 ArkTS 代码必须通过编译验证(`BUILD SUCCESSFUL`)才可交付。本文档说明验证机制、工具用法与错误修复。
4
+
5
+ ---
6
+
7
+ ## 一、核心机制:构建图可达性
8
+
9
+ hvigor 编译器只编译**构建图可达**的 .ets 文件:
10
+
11
+ ```
12
+ entry/src/main/ets/pages/Index.ets(页面,注册于 main_pages.json)
13
+ └── import → 组件/工具类
14
+ └── import → 更深层模块
15
+ ```
16
+
17
+ - 被页面/入口 import 链引用的文件 → 参与编译,语法/约束错误全部暴露
18
+ - **未被引用的孤立 .ets 文件 → 完全不编译,错误不会暴露**
19
+
20
+ 因此验证前必须确保新代码已接入构建图。两种方式:
21
+
22
+ | 方式 | 操作 | 适用 |
23
+ |------|------|------|
24
+ | 工程内接线 | 新页面注册 `main_pages.json`;新类被页面/`index.ets` import | 有目标工程 |
25
+ | 自动接线 | `verify-arkts.cjs` 脚本在临时工程入口页生成 side-effect import(`import '../verify/Xxx';`) | 独立代码验证 |
26
+
27
+ > side-effect import(无绑定导入)足以让目标文件参与编译并暴露全部错误,无需知道文件内导出符号名。
28
+
29
+ ---
30
+
31
+ ## 二、工程模式验证
32
+
33
+ ```bash
34
+ # 在目标工程根目录执行
35
+ devecocli build
36
+
37
+ # 指定模块/产物
38
+ devecocli build --modules entry
39
+ devecocli build --product default --build-mode debug
40
+
41
+ # 清理后构建(怀疑缓存问题时)
42
+ devecocli build clean && devecocli build
43
+ ```
44
+
45
+ **前置检查**:新代码已按 Phase 3.5 接线(页面注册 / import 可达),否则构建通过不代表语法正确。
46
+
47
+ **结果判定**:只认 `BUILD SUCCESSFUL`;`ERROR` 必须清零,`WARNING` 记录但不阻断。
48
+
49
+ ---
50
+
51
+ ## 三、独立模式验证(verify-arkts.cjs)
52
+
53
+ 无目标工程时,使用本SKILL自带脚本自动完成"脚手架 → 接线 → 编译 → 回显错误":
54
+
55
+ ```bash
56
+ node {本SKILL目录}/scripts/verify-arkts.cjs --files <文件1.ets> [文件2.ets ...] [选项]
57
+ ```
58
+
59
+ | 选项 | 说明 |
60
+ |------|------|
61
+ | `--files <f.ets>...` | 待验证的 .ets 文件(至少 1 个;多文件间相对导入按原目录结构保留) |
62
+ | `--work-dir <目录>` | 临时工程所在目录(默认系统临时目录,验证后删除;指定后工程保留可复用加速下次验证) |
63
+ | `--keep` | 保留临时工程(默认自动删除) |
64
+ | `--api-level <n>` | 指定脚手架 API Level(默认用 devecocli 默认值) |
65
+ | `--timeout <ms>` | 构建超时(默认 600000) |
66
+
67
+ **MCP Gateway 调用**(JSON 参数):
68
+
69
+ ```json
70
+ { "files": ["/abs/path/Foo.ets", "/abs/path/Bar.ets"], "workDir": "/tmp/arkts-verify", "keep": false }
71
+ ```
72
+
73
+ **退出码**:`0` 验证通过;`1` 存在编译错误(输出结构化错误列表);`2` 环境/参数错误。
74
+
75
+ **输出示例(失败)**:
76
+
77
+ ```
78
+ === ArkTS 编译验证失败(3 个错误) ===
79
+ [arkts-no-any-unknown] /abs/path/Foo.ets:2:17
80
+ Use explicit types instead of "any", "unknown"
81
+ ...
82
+ ```
83
+
84
+ **注意**:
85
+ - 引用了工程专属资源(`$r('app.string.xxx')`、rawfile、自定义 so 库)的代码无法在临时工程验证,须用工程模式
86
+ - 首次运行需脚手架(约 10-60s);指定 `--work-dir` 复用可加速
87
+ - 需要本机已安装 DevEco Studio + SDK + devecocli 可用
88
+
89
+ ---
90
+
91
+ ## 四、错误输出解析
92
+
93
+ `devecocli build` 的 ArkTS 编译错误格式(用于定位):
94
+
95
+ ```
96
+ N ERROR: 10605008 ArkTS Compiler Error
97
+ Error Message: <人读信息> (arkts-规则名) At File: <绝对路径>:<行>:<列>
98
+ ```
99
+
100
+ 解析要点:
101
+ - 规则名在**圆括号**内,如 `(arkts-no-any-unknown)`
102
+ - 位置为 `文件:行:列`,列指向违规 token 起点
103
+ - 同一文件多个错误一次全部修复再重跑,避免逐个循环
104
+
105
+ ---
106
+
107
+ ## 五、错误修复速查表
108
+
109
+ | 错误关键词 / 规则 | 修复方案 |
110
+ |-----------------|---------|
111
+ | `arkts-no-any-unknown` | `any`/`unknown` → 具体类型或泛型 `T`;`as any` → `as 具体类型` |
112
+ | `arkts-no-esobj` | `ESObject`/`Object` → `interface` 或具体类型 |
113
+ | `arkts-no-untyped-obj-literals` | `let o = {...}` → 先声明 `interface`/`class`,再 `const o: T = {...}` |
114
+ | `arkts-no-obj-literals-as-types` | 匿名对象类型参数 → 命名 `interface` |
115
+ | `arkts-limited-throw` | `throw e` → `throw e instanceof Error ? e : new Error(String(e))` |
116
+ | `arkts-no-dynamic-property` | `obj['key']` → `obj.key` |
117
+ | `arkts-no-structural-typing` | 鸭子类型赋值 → 显式 `implements` / `extends` |
118
+ | `arkts-no-unsafe-cast` | `as unknown as T` → 修正类型定义,单次断言 |
119
+ | `arkts-no-delete` | `delete obj.x` → `obj.x = undefined` 或重构结构 |
120
+ | `arkts-no-for-in` | `for...in` → `Object.keys()` + `for...of` |
121
+ | `arkts-no-prototype-assignment` | 原型扩展 → 类继承/组合 |
122
+ | `arkts-no-arguments` | `arguments` → `...args: T[]` |
123
+ | `Cannot find module 'xxx'` | import 路径拼写/大小写;相对层级;`@ohos.*` 模块名以文档为准 |
124
+ | `xxx has been deprecated` | 查官方文档替代 API,禁止保留 |
125
+ | `Page 'xxx' does not exist` | `main_pages.json` 与实际页面文件对齐 |
126
+ | `Permission denied` / 权限类 | `module.json5` `requestPermissions` 声明(对照 Phase 2 查证表) |
127
+ | `undefined property` / 资源类 | `$r` 资源需存在于 `resources/base/element`;rawfile 走 resourceManager |
128
+ | 装饰器报错 | `@Component` struct 不能继承;`@Concurrent` 函数不能捕获外部变量 |
129
+ | ArkUI 状态更新不生效 | build() 内禁止修改状态变量;修改放事件回调 |
130
+
131
+ ---
132
+
133
+ ## 六、辅助检查(可选补充)
134
+
135
+ ### 6.1 Code Linter(代码风格/安全规则)
136
+
137
+ ```bash
138
+ devecocli check lint <文件或目录> [--fix] [--format json]
139
+ ```
140
+
141
+ - 检查 TS/ArkTS 风格问题(`@performance/recommended`、`@typescript-eslint/recommended`、`@security/*`)
142
+ - 依赖工程上下文(`build-profile.json5`),且部分环境需工程完成同步后才识别文件(`Files checked: 0` 说明未识别到目标)
143
+ - **lint 通过 ≠ 语法正确**,仅作为风格/安全补充;最终以 `devecocli build` 为准
144
+
145
+ ### 6.2 版本兼容检查
146
+
147
+ ```bash
148
+ devecocli check compat versions # 列出可用 SDK 版本
149
+ devecocli check compat --source-version "<V1>" --target-version "<V2>"
150
+ devecocli check compat --source-version "<V1>" --target-version "<V2>" <文件...>
151
+ ```
152
+
153
+ 检查代码使用的 API 在目标 SDK 版本是否存在/已变更,适合交付前核对 API Level 兼容性。
154
+
155
+ > zsh 下版本号含括号,务必加引号;先用 `compat versions` 复制真实版本串。
156
+
157
+ ---
158
+
159
+ ## 七、验证纪律
160
+
161
+ 1. **一次性修复**:收集全部 ERROR 后统一修复,再重新构建
162
+ 2. **修复循环上限 5 轮**:超过后停止,向用户报告错误清单与已尝试方案
163
+ 3. **禁止降低验证标准**:不允许通过注释掉代码、放宽 lint 配置等方式"绕过"错误
164
+ 4. **速查表未覆盖的错误**:用 `script_deveco_docs` 查证涉事 API 的正确用法,或查阅 [ArkTS 规范与约束](ARKTS_RULES.md) 对应条目