• Home
Name Date Size #Lines LOC

..--

.vscode/06-May-2025-3534

bin/06-May-2025-1815

scripts/06-May-2025-2,8972,662

src/06-May-2025-22,36519,106

test/06-May-2025-118,876101,899

.gitignoreD06-May-202534 44

BUILD.gnD06-May-20252.2 KiB6344

LICENSED06-May-202510.9 KiB196166

OAT.xmlD06-May-20253.7 KiB5811

README-cn.mdD06-May-202520.7 KiB581422

README.mdD06-May-202522.8 KiB602448

Version.mdD06-May-2025371 1510

compile_arkguard.pyD06-May-20252.3 KiB7546

package-lock.jsonD06-May-202538.7 KiB937936

package.jsonD06-May-20252.2 KiB6666

tsconfig.base.jsonD06-May-2025905 2726

tsconfig.jsonD06-May-2025316 1817

README-cn.md

1# 文档更新说明
2
3## 该文档不再维护,后续混淆文档迁移至[官方指南](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5)以及[社区doc仓](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/arkts-utils/source-obfuscation.md)
4
5注:代码混淆功能与DevEco Studio版本同步更新,建议优先阅读与DevEco Studio版本配套的官方指南。
6社区doc仓文档对应开源代码,领先于发布的DevEco Studio中的代码混淆功能。
7
8# Arkguard
9
10Arkguard 是Javascript和Typescript的源码混淆工具。
11
12# 在DevEco Studio中的用法
13
14Arkguard已经被集成了到SDK中。可以在DevEco Studio中很方便地使用。Arkguard只能用于Stage模型
15(不支持FA模型)。目前Arkguard只提供名称混淆的能力(因为其它混淆能力会劣化性能)。
16使用Arkguard可以混淆以下名称:
17
18* 参数名和局部变量名
19* 顶层作用域的名称
20* 属性名称
21
22Arkguard默认使能对参数名和局部变量名的混淆。顶层作用域名称和属性名称的混淆是默认关闭的,
23因为默认打开可能会导致运行时错误。你可以通过[混淆选项](#混淆选项)来开启它们。
24
25创建一个新工程的时候,配置文件`build-profile.json5`中会自动生成以下内容:
26
27```
28"arkOptions": {
29  "obfuscation": {
30    "ruleOptions": {
31      "enable": true,
32      "files": ["obfuscation-rules.txt"],
33    }
34  }
35}
36```
37
38创建一个新的library的时候,还会额外生成`consumerFiles`属性:
39
40```
41"arkOptions": {
42  "obfuscation": {
43    "ruleOptions": {
44      "enable": true,
45      "files": ["obfuscation-rules.txt"],
46    }
47    "consumerFiles": ["consumer-rules.txt"]
48  }
49}
50```
51
52要想开启混淆,需要满足下面的条件:
53
54* 属性`ruleOptions.enable`的值为`true`,并且所有依赖的library的`ruleOptions.enable`属性是`true`
55* 在release模式构建
56
57属性`ruleOptions.files`中指定的混淆配置文件会在构建HAP或HAR的时候被应用。
58
59属性`consumerFiles`中指定的混淆配置文件会在构建依赖这个library的工程或library时被应用。
60这些混淆配置文件的内容还会被合并到HAR包中的`obfuscation.txt`文件。
61
62当构建HAP或者HAR的时候,最终的混淆规则是自身的`ruleOptions.files`属性,依赖的library的`consumerFiles`属性,
63以及依赖的HAR包中的`obfuscation.txt`文件的合并。如果构建的是HAR,`obfuscation.txt`是自身的`consumerFiles`属性,
64依赖的library的`consumerFiles`属性,以及依赖的HAR包中的`obfuscation.txt`文件的合并。
65构建HAP不会生成`obfuscation.txt`。详细合并的策略可以查看[混淆规则合并策略](#混淆规则合并策略)。
66
67## 配置混淆规则
68
69在创建工程或library的时候,DevEco Studio会自动生成`obfuscation-rules.txt`和`consumer-rules.txt`文件,
70但是它们默认不会包含任何混淆规则。你可以在这些文件中写混淆规则,或者也可以将规则写在其它文件,
71然后将文件路径放到`ruleOptions.files`和`consumerFiles`中,如下面的例子所示。
72
73```
74"buildOption": {
75  "arkOptions": {
76    "obfuscation": {
77      "ruleOptions": {
78        "enable": true,
79        "files": ["obfuscation-rules.txt", "myrules.txt"],
80      }
81      "consumerFiles": ["consumer-rules.txt", "my-consumer-rules.txt"]
82    }
83  }
84}
85```
86
87在混淆规则文件中,你可以写[混淆选项](#混淆选项)和[保留选项](#保留选项)。
88
89### 混淆选项
90
91#### -disable-obfuscation
92
93关闭所有混淆。如果你使用这个选项,那么构建出来的HAP或HAR将不会被混淆。默认情况下,
94Arkguard只混淆参数名和局部变量名(通过将它们重新命名为随机的短名字)。
95
96#### -enable-property-obfuscation
97
98开启属性混淆。 如果你使用这个选项,那么所有的属性名都会被混淆,除了下面场景:
99
100* 被`import/export`直接导入或导出的类或对象的属性名不会被混淆。比如下面例子中的属性名`data`不会被混淆。
101
102    ```
103    export class MyClass {
104       data: string;
105    }
106    ```
107
108    对于间接导出的场景,比如`export MyClass`和`let a = MyClass; export {a};`,如果你不想混淆它们的属性名,那么你需要使用[保留选项](#保留选项)来保留这些属性名。另外,对于直接导出的类或对象的属性的属性名,比如下面例子中的`name`和`age`, 如果你不想混淆它们,那么你也需要使用[保留选项](#保留选项)来保留这些属性名。
109
110    ```
111    export class MyClass {
112       person = {name: "123", age: 100};
113    }
114    ```
115
116    如果想混淆直接导入/导出的名称,请参考[`-enable-export-obfuscation`](#-enable-export-obfuscation)选项。
117* ArkUI组件中的属性名不会被混淆。比如下面例子中的`message`和`data`不会被混淆。
118
119    ```
120    @Component struct MyExample {
121        @State message: string = "hello";
122        data: number[] = [];
123        ...
124    }
125    ```
126
127* 被[保留选项](#保留选项)指定的属性名不会被混淆。
128* 系统API列表中的属性名不会被混淆。系统API列表是构建时从SDK中自动提取出来的一个名称列表,其缓存文件为systemApiCache.json,路径为工程目录下build/cache/{...}/release/obfuscation129* 在Native API场景中,在so的d.ts文件中声明的API不会被混淆。
130* 字符串字面量属性名不会被混淆。比如下面例子中的`"name"`和`"age"`不会被混淆。
131
132    ```
133    let person = {"name": "abc"};
134    person["age"] = 22;
135    ```
136
137    如果你想混淆字符串字面量属性名,你需要在该选项的基础上再使用`-enable-string-property-obfuscation`选项。比如
138
139    ```
140    -enable-property-obfuscation
141    -enable-string-property-obfuscation
142    ```
143
144    **注意**:
145    **1.** 如果代码里面有字符串属性名包含特殊字符(除了`a-z, A-Z, 0-9, _`之外的字符),比如`let obj = {"\n": 123, "": 4, " ": 5}`,建议不要开启`-enable-string-property-obfuscation`选项,因为当不想混淆这些名字时,可能无法通过[保留选项](#保留选项)来指定保留这些名字。
146    **2.** 系统API的属性白名单中不包含声明文件中使用的字符串常量值,比如示例中的字符串'ohos.want.action.home'不被包含在属性白名单中
147
148    ```
149    // 系统API文件@ohos.app.ability.wantConstant片段:
150    export enum Params {
151      ACTION_HOME = 'ohos.want.action.home'
152    }
153    // 开发者源码示例:
154    let params = obj['ohos.want.action.home'];
155    ```
156
157    因此在开启了`-enable-string-property-obfuscation`选项时,如果想保留代码中使用的系统API字符串常量的属性不被混淆,比如obj['ohos.want.action.home'], 那么需要使用keep选项保留。
158
159#### -enable-toplevel-obfuscation
160
161开启顶层作用域名称混淆。如果你使用这个选项,那么所有的顶层作用域的名称都会被混淆,除了下面场景:
162
163* 被`import/export`的名称不会被混淆。
164* 当前文件找不到声明的名称不会被混淆。
165* 被[保留选项](#保留选项)指定的顶层作用域名称不会被混淆。
166* 系统API列表中的顶层作用域名称不会被混淆。
167
168#### -enable-filename-obfuscation
169
170开启文件/文件夹名称混淆。如果使用这个选项,那么所有的文件/文件夹名称都会被混淆,除了下面场景:
171
172* oh-package.json5文件中'main'、'types'字段配置的文件/文件夹名称不会被混淆。
173* 模块内module.json5文件中'srcEntry'字段配置的文件/文件夹名称不会被混淆。
174* 被[`-keep-file-name`](#保留选项)指定的文件/文件夹名称不会被混淆。
175* 非ECMAScript模块引用方式(ECMAScript模块示例:`import {foo} from './filename'`)
176* 非路径引用方式,比如例子中的json5不会被混淆 `import module from 'json5'`
177
178**注意**:
179**1.** 由于系统会在应用运行时加载某些指定的文件,针对这类文件,开发者需要手动在[`-keep-file-name`]选项中配置相应的白名单,防止指定文件被混淆,导致运行失败。
180上述需要手动配置白名单的情况,包括但不限于以下场景:
181(1) 当模块中包含Ability组件时。用户需要将`scr/main/module.json5`中,'abilities'字段下所有'srcEntry'对应的路径配置到白名单中。
182(2) 当模块中包含Worker多线程服务时,用户需要将`build-profiles.json5`中,'buildOption'-'sourceOption'-'workers'字段下所有的路径配置到白名单中。
183
184#### -enable-export-obfuscation
185
186开启直接导入或导出的类或对象的名称和属性名混淆。如果使用这个选项,那么模块中的直接导入或导出的名称都会被混淆,除了下面场景:
187
188* 远程HAR(真实路径在oh_modules中的包)中导出的类或对象的名称和属性名不会被混淆。
189* 被[保留选项](#保留选项)指定的名称与属性名不会被混淆。
190* 系统API列表中的名称不会被混淆。
191
192**注意**:
193
1941. 混淆导入或导出的类中属性名称需要同时开启`-enable-property-obfuscation`与`-enable-export-obfuscation`选项。
1952. 编译HSP时,如果开启`-enable-export-obfuscation`选项,需要在模块中的混淆配置文件`obfuscation-rules.txt`中保留对外暴露的接口。
1963. HAP/HSP/HAR依赖HSP场景下,编译时如果开启`-enable-export-obfuscation`选项,需要在模块中的混淆配置文件`obfuscation-rules.txt`中保留HSP导入的接口。
197
198    ```
199    // 代码示例(HSP中入口文件Index.ets):
200    export { add, customApiName } from './src/main/ets/utils/Calc'
201
202    // 保留接口名称配置示例:
203    // HSP以及依赖此HSP的模块中obfuscation-rules.txt文件配置:
204    keep-global-name
205    add
206    customApiName
207    ```
208
209#### -compact
210
211去除不必要的空格符和所有的换行符。如果使用这个选项,那么所有代码会被压缩到一行。
212**注意**:release模式构建的应用栈信息仅包含代码行号,不包含列号,因此compact功能开启后无法依据报错栈中的行号定位到源码具体位置。
213
214#### -remove-log
215
216删除以下场景中对 console.*语句的调用,要求console.*语句返回值未被调用。
217
2181. 文件顶层的调用
2192. 代码块Block中的调用
2203. 模块Module中的调用
2214. switch语句中的调用
222
223#### `-print-namecache` filepath
224
225将名称缓存保存到指定的文件路径。名称缓存包含名称混淆前后的映射。
226注意:每次全量构建工程时都会生成新的namecache.json文件,因此您每次发布新版本时都要注意保存一个该文件的副本。
227
228#### `-apply-namecache` filepath
229
230复用指定的名称缓存文件。名字将会被混淆成缓存映射对应的名字,如果没有对应,将会被混淆成新的随机段名字。
231该选项应该在增量编译场景中被使用。
232
233默认情况下,DevEco Studio会在临时的缓存目录中保存缓存文件,并且在增量编译场景中自动应用该缓存文件。
234缓存目录:build/cache/{...}/release/obfuscation
235
236#### -remove-comments
237
238删除文件中的所有注释,包括单行、多行,及JsDoc注释。以下场景除外:
239声明文件中,在`-keep-comments`中配置的类、方法、struct、枚举等名称上方的JsDoc注释。
240**注意**:编译生成的源码文件中的注释默认会被全部删除,不支持配置保留。
241
242### 保留选项
243
244#### `-keep-property-name` [,identifiers,...]
245
246指定你想保留的属性名。比如下面的例子:
247
248```
249-keep-property-name
250age
251firstName
252lastName
253```
254
255**注意**:该选项在开启`-enable-property-obfuscation`时生效
256
257`-keep-comments`
258保留声明文件中元素上方的JsDoc注释。比如想保留声明文件中Human类上方的JsDoc注释,可进行以下配置:
259
260```
261-keep-comments
262Human
263```
264
265**注意**:
266
2671. 该选项在开启`-remove-comments`时生效
2682. 当声明文件中某个元素名称被混淆时,该元素上方的JsDoc注释无法通过`-keep-comments`保留。比如当在`-keep-comments`中配置了
269exportClass时,如果下面的类名被混淆,其JsDoc注释无法被保留:
270
271```
272/**
273** @class exportClass
274*/
275export class exportClass {}
276```
277
278**哪些属性名应该被保留?**
279
280为了保障混淆的正确性,我们建议你保留所有不通过点语法访问的属性。
281
282例子:
283
284```
285var obj = {x0: 0, x1: 0, x2: 0};
286for (var i = 0; i <= 2; i++) {
287    console.log(obj['x' + i]);  // x0, x1, x2 应该被保留
288}
289
290Object.defineProperty(obj, 'y', {});  // y 应该被保留
291console.log(obj.y);
292
293obj.s = 0;
294let key = 's';
295console.log(obj[key]);        // s 应该被保留
296
297obj.u = 0;
298console.log(obj.u);           // u 可以被正确地混淆
299
300obj.t = 0;
301console.log(obj['t']);        // 在开启字符串字面量属性名混淆时t和't'会被正确地混淆,但是我们建议保留
302
303obj['v'] = 0;
304console.log(obj['v']);        // 在开启字符串字面量属性名混淆时'v'会被正确地混淆,但是我们建议保留
305```
306
307在Native API场景中,没有在so的d.ts文件中声明的API,如果要在ets/ts/js文件中使用需要手动保留。
308
309#### `-keep-global-name` [,identifiers,...]
310
311指定要保留的顶层作用域的名称。比如,
312
313```
314-keep-global-name
315Person
316printPersonName
317```
318
319**哪些顶层作用域的名称应该被保留?**
320
321在Javascript中全局变量是`globalThis`的属性。如果在代码中使用`globalThis`去访问全局变量,那么该变量名应该被保留。
322
323例子:
324
325```
326var a = 0;
327console.log(globalThis.a);  // a 应该被保留
328
329function foo(){}
330globalThis.foo();           // foo 应该被保留
331
332var c = 0;
333console.log(c);             // c 可以被正确地混淆
334
335function bar(){}
336bar();                      // bar 可以被正确地混淆
337
338class MyClass {}
339let d = new MyClass();      // MyClass 可以被正确地混淆
340```
341
342#### `-keep-file-name` [,identifiers,...]
343
344指定要保留的文件/文件夹的名称(不需要写文件后缀)。比如,
345
346```
347-keep-file-name
348index
349entry
350```
351
352**哪些文件名应该被保留?**
353
354```
355const module1 = require('./file1')   // ARKTs不支持CommonJS语法,这种路径引用应该被保留
356const moduleName = './file2'
357const module2 = import(moduleName)    // 动态引用方式无法识别moduleName是否是路径,应该被保留
358```
359
360#### `-keep-dts` filepath
361
362保留指定路径的`.d.ts`文件中的名称。这里的文件路径可以是一个目录,这种情况下目录中所有`.d.ts`文件中的名称都会被保留。
363如果在构建HAR时使用了这个选项,那么文件中的名称会被合并到最后的`obfuscation.txt`文件中。
364
365#### `-keep` path
366
367保留指定路径中的所有名称(例如变量名、类名、属性名等)不被混淆。这个路径可以是文件与文件夹,若是文件夹,则文件夹下的文件及子文件夹中文件都不混淆。
368路径仅支持相对路径,`./`与`../`为相对于混淆配置文件所在目录。
369
370```
371-keep
372./src/main/ets/fileName.ts   // fileName.ts中的名称不混淆
373../folder                    // folder目录下文件及子文件夹中的名称都不混淆
374../oh_modules/json5          // 引用的三方库json5里所有文件中的名称都不混淆
375```
376
377注:该功能不影响文件名混淆`-enable-filename-obfuscation`的功能
378
379### 保留选项支持通配符
380
381#### 名称类通配符
382
383以下保留选项支持配置名称类通配符:
384
385`-keep-property-name`
386
387`-keep-global-name`
388
389`-keep-file-name`
390
391`-keep-comments`
392
393名称类通配符使用方式如下:
394
395| 通配符 | 含义                   | 示例                                       |
396| ------ | ---------------------- | ------------------------------------------ |
397| ?      | 匹配任意单个字符       | "AB?"能匹配"ABC"等,但不能匹配"AB"         |
398| \*     | 匹配任意数量的任意字符 | "\*AB\*"能匹配"AB"、"aABb"、"cAB"、"ABc"等 |
399
400**使用示例**:
401
402保留所有以a开头的属性名称:
403
404```
405-keep-property-name
406a*
407```
408
409保留所有单个字符的属性名称:
410
411```
412-keep-property-name
413?
414```
415
416保留所有属性名称:
417
418```
419-keep-property-name
420*
421```
422
423#### 路径类通配符
424
425以下保留选项支持配置路径类通配符:
426
427`-keep`
428
429路径类通配符使用方式如下:
430
431| 通配符 | 含义                                                                     | 示例                                              |
432| ------ | ------------------------------------------------------------------------ | ------------------------------------------------- |
433| ?      | 匹配任意单个字符,除了路径分隔符'/'                                      | "../a?"能匹配"../ab"等,但不能匹配"../a/"         |
434| \*     | 匹配任意数量的任意字符,除了路径分隔符'/'                                | "../a*/c"能匹配"../ab/c",但不能匹配"../ab/d/s/c" |
435| \*\*   | 匹配任意数量的任意字符                                                   | "../a**/c"能匹配"../ab/c",也能匹配"../ab/d/s/c"  |
436| !      | 表示非,只能写在某个路径最前端,用来排除用户配置的白名单中已有的某种情况 | "!../a/b/c.ets"表示除"../a/b/c.ets"以外           |
437
438**使用示例**:
439
440表示路径../a/b/中所有文件夹(不包含子文件夹)中的c.ets文件不会被混淆:
441
442```
443-keep
444../a/b/*/c.ets
445```
446
447表示路径../a/b/中所有文件夹(包含子文件夹)中的c.ets文件不会被混淆:
448
449```
450-keep
451../a/b/**/c.ets
452```
453
454表示路径../a/b/中,除了c.ets文件以外的其它文件都不会被混淆:
455
456```
457-keep
458../a/b/
459!../a/b/c.ets
460```
461
462无意义:
463
464```
465-keep
466!../a/b/c.ets
467```
468
469表示所有文件都不会被混淆:
470
471```
472-keep
473*
474```
475
476**注意**:
477
478(1)以上选项,不支持配置通配符'*'、'?'、'!'作其它含义使用。
479例如:
480
481```
482class A {
483  '*'= 1
484}
485
486-keep-property-name
487*
488```
489
490此时'\*'表示匹配任意数量的任意字符,配置效果为所有属性名称都不混淆,而不是只有'\*'属性不被混淆。
491
492(2)-keep选项中只允许使用'/'路径格式,不支持'\\'或'\\\\'。
493
494### 注释
495
496可以使用`#`在混淆规则文件中进行注释。每行以`#`开头的文本会被当做是注释,比如下面的例子:
497
498```
499# white list for MainAbility.ets
500-keep-global-name
501MyComponent
502GlobalFunction
503
504-keep-property-name # white list for dynamic property names
505firstName
506lastName
507age
508```
509
510构建HAR时,注释不会被合并到最后的`obfuscation.txt`文件中。
511
512### 混淆规则合并策略
513
514一个工程中经常会有许多混淆规则文件,这些文件来自于:
515
516* 主工程的`ruleOptions.files` (这里主工程我们指的是正在构建的工程)
517* 本地依赖的library中的`consumerFiles`选项中指定的文件
518* 远程依赖的HAR包中的`obfuscate.txt`文件
519
520当构建主工程的时候,这些文件中的混淆规则会按照下面的合并策略(伪代码)进行合并:
521
522```
523let `listRules` 表示上面提到的所有混淆规则文件的列表
524let finalRule = {
525    disableObfuscation: false,
526    enablePropertyObfuscation: false,
527    enableToplevelObfuscation: false,
528    compact: false,
529    removeLog: false,
530    keepPropertyName: [],
531    keepGlobalName: [],
532    keepDts: [],
533    printNamecache: string,
534    applyNamecache: string
535}
536for each file in `listRules`:
537    for each option in file:
538        switch(option) {
539            case -disable-obfuscation:
540                finalRule.disableObfuscation = true;
541                continue;
542            case -enable-property-obfuscation:
543                finalRule.enablePropertyObfuscation = true;
544                continue;
545            case -enable-toplevel-obfuscation:
546                finalRule.enableToplevelObfuscation = true;
547                continue;
548            case -compact:
549                finalRule.compact = true;
550                continue;
551            case -remove-log:
552                finalRule.removeLog = true;
553                continue;
554            case -print-namecache:
555                finalRule.printNamecache = #{指定的路径名};
556                continue;
557            case -apply-namecache:
558                finalRule.applyNamecache = #{指定的路径名};
559                continue;
560            case -keep-property-name:
561                finalRule.keepPropertyName.push(#{指定的名称});
562                continue;
563            case -keep-global-name:
564                finalRule.keepGlobalName.push(#{指定的名称});
565                continue;
566            case -keep-dts:
567                finalRule.keepDts.push(#{指定的路径});
568                continue;
569        }
570    end-for
571end-for
572```
573
574最后使用的混淆规则来自于对象`finalRule`。
575
576如果构建的是HAR,那么最终的`obfuscate.txt`文件内容来自于主工程和本地依赖的library的`consumerFiles`选项,
577以及依赖的HAR的`obfuscate.txt`文件的合并。合并策略和上面一样,除了以下的不同:
578
579* `-keep-dts`选项会被转换成`-keep-global-name`和`-keep-property-name`。
580* `-print-namecache`和`apply-namecache`选项会被忽略,不会出现在最后的`obfuscate.txt`文件中。
581

README.md

1# Document update instructions
2
3## This document is no longer maintained. Obfuscation documents will be moved to [official guide](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5) and [doc repository](https://gitee.com/openharmony/docs/blob/master/en/application-dev/arkts-utils/source-obfuscation.md)
4
5Note: The source obfuscation is updated synchronously with the DevEco Studio version. It is recommended to read the official guide that comes with the DevEco Studio version first. The community doc repository correspond to the latest open source code, ahead of the source obfuscation function in the released DevEco Studio.
6
7# Arkguard
8
9Arkguard is a javascript and typescript obfuscation tool.
10For Chinese version please read [README-cn.md](README-cn.md)
11(中文版说明请查看[README-cn.md](README-cn.md)).
12
13# Usage in DevEco Studio
14
15Arkguard has been integrated into SDK. It is convenient to use Arkguard in DevEco Studio.
16In DevEco Studio, Arkguard can be enabled only in Stage Model (FA Model is not supported).
17For now only name obfuscations can be used in DevEco Studio (because other obfuscation
18abilities of Arkguard may hurt execution performance).
19You can obfuscate the following names:
20
21* parameter names and local variable names
22* names in global scope
23* property names
24
25We enable the obfuscation of parameter names and local variable names by default. However,
26global names obfuscation and property names obfuscation are disabled by default, as they may
27cause runtime error if they are enabled by default.
28You can enable them by [obfuscation options](#obfuscation-options).
29
30When you create a new project, the following config will be generated in `build-profile.json5`.
31
32```
33"arkOptions": {
34  "obfuscation": {
35    "ruleOptions": {
36      "enable": true,
37      "files": ["obfuscation-rules.txt"],
38    }
39  }
40}
41```
42
43When you create a new library, additional property `consumerFiles` will be added.
44
45```
46"arkOptions": {
47  "obfuscation": {
48    "ruleOptions": {
49      "enable": true,
50      "files": ["obfuscation-rules.txt"],
51    }
52    "consumerFiles": ["consumer-rules.txt"]
53  }
54}
55```
56
57To enable obfuscation, the following conditions should be satisfied:
58
59* the property `ruleOptions.enable` is `true` and the property `ruleOptions.enable` of every dependent library is `true`.
60* build in release mode
61
62The files in the property `ruleOptions.files` will be applied when you build HAP or HAR.
63
64The files in the property `consumerFiles` will be applied when you build the project or library which
65depends on this library. They will also be merged into a file `obfuscation.txt` in the resulting HAR.
66
67When you are building HAP or HAR, the final obfucation rules are combination of self's `ruleOptions.files`
68property, dependent libraries' `consumerFiles` properties and dependent HAR's `obfuscation.txt`.
69If you are building HAR, the content of `obfuscation.txt` is the combination of self's `consumerFiles` property,
70dependent libraries' `consumerFiles` properties and dependent HAR's `obfuscation.txt`. If you are building
71HAP, `obfuscation.txt` will not be generated. For more details, please jump to
72"[How Arkguard merges rules](#how-arkguard-merges-rules)".
73
74## Write rules
75
76The files `obfuscation-rules.txt` and `consumer-rules.txt` are created by DevEco Studio automatically, but they do not
77contain any rule by default. You can write rules in these files or include rules from other files, as the following
78example shows.
79
80```
81"buildOption": {
82  "arkOptions": {
83    "obfuscation": {
84      "ruleOptions": {
85        "enable": true,
86        "files": ["obfuscation-rules.txt", "myrules.txt"],
87      }
88      "consumerFiles": ["consumer-rules.txt", "my-consumer-rules.txt"]
89    }
90  }
91}
92```
93
94In rule files, you can write [obfuscation options](#obfuscation-options) and [keep options](#keep-options).
95
96### Obfuscation options
97
98#### -disable-obfuscation
99
100Specifies to disable all obfuscations. If you use this option, the resulting HAP or HAR will not be obfuscated. By default,
101Arkguard only obfuscates the parameter names and local variable names by assigning random short names to them.
102
103#### -enable-property-obfuscation
104
105Specifies to obfuscate the property names. If you use this option, all property names will be obfuscated except the
106following:
107
108* the property names of classes or objects directly imported or exported by `import/export` will be kept. For example, the property name `data` in
109
110    ```
111    export class MyClass {
112       data: string;
113    }
114    ```
115
116    will not be obfuscated.
117For 'indirectly export' cases such as `export MyClass` and `let a = MyClass; export {a};`, if you do not want to obfuscate
118their property names, you need to use [keep options](#keep-options) to keep them. Besides, for the property names of properties of directly exported classes or objects, like `name` and `age` in the following example, if you do not want to obfuscate them, then you also need [keep options](#keep-options) to keep them.
119
120    ```
121    export class MyClass {
122       person = {name: "123", age: 100};
123    }
124    ```
125
126    If you want to obfuscate import/export names, please refer to the [`-enable-export-obfuscation`](#-enable-export-obfuscation) option.
127* the property names defined in UI components. For example, the property names `message` and `data` in
128
129    ```
130    @Component struct MyExample {
131        @State message: string = "hello";
132        data: number[] = [];
133        ...
134    }
135    ```
136
137    will not be obfuscated.
138* the property names that are specified by [keep options](#keep-options).
139* the property names in system API list. System API list is a name set which is extracted from SDK automatically by default. The cache file is systemApiCache.json, and the path is build/cache/{...}/release/obfuscation in the module directory.
140* in the Native API scenario, the APIs in the d.ts file of so library will not be obfuscated.
141* the property names that are string literals. For example, the property names "name" and "age" in the following code will not be obfuscated.
142
143    ```
144    let person = {"name": "abc"};
145    person["age"] = 22;
146    ```
147
148    If you want to obfuscate these string literal property names, you should addtionally use the option `-enable-toplevel-obfuscation`. For example,
149
150    ```
151    -enable-property-obfuscation
152    -enable-string-property-obfuscation
153    ```
154
155    **Note**:
156    **1.** If there are string literal property names which contain special characters (that is, all characters except
157    `a-z, A-Z, 0-9, _`, for example `let obj = {"\n": 123, "": 4, " ": 5}` then we would not suggest to enable the
158    option `-enable-string-property-obfuscation`, because [keep options](#keep-options) may not allow to keep these
159    names when you do not want to obfuscate them.
160    **2.** The property white list of the system API does not include the string constant in the declaration file. For example, the string `'ohos.want.action.home'` in the example is not included in the white list.
161
162    ```
163    // System Api @ohos.app.ability.wantConstant snippet:
164    export enum Params {
165      DLP_PARAM_SANDBOX = 'ohos.dlp.param.sandbox'
166    }
167    // Developer source example:
168    let params = obj['ohos.want.action.home'];
169    ```
170
171    Therefore, when `-enable-string-property-obfuscation` is enabled, if you don't want to obfuscate the property like `'ohos.dlp.param.sandbox'`, which is a string constant in system api. you should keep it manually.
172
173Specifies to obfuscate the names in the global scope. If you use this option, all global names will be obfuscated
174except the following:
175
176* the `import/export` global names.
177* the global names that are not declared in the current file.
178* the global names that are specified by [keep options](#keep-options).
179* the global names in system API list.
180
181#### -enable-filename-obfuscation
182
183Specifies to obfuscate the file/folder names. If you use this option, all file/folder names will be obfuscated except the following:
184
185* the file/folder names configured in the 'main' and 'types' fields in the oh-package.json5.
186* the file/folder names configured in the 'srcEntry' field in the module.json5.
187* the file/folder names that are specified by [`-keep-file-name`](#keep-options).
188* non-ECMAScript module reference (ECMAScript module example: `import {foo} from './filename'`)
189* non-path reference, such as json5 will not be obfuscated `import module from 'json5'`
190**Note**:
191**1.** Due to the system loading certain specified files during application runtime, developers need to configure the corresponding white list manually in the [` keep file name `] option to prevent specified files from being confused and causing runtime failures.
192The above situations that require configure white list manually include but are not limited to the following scenarios:
193(1) When the module contains Ability component, you need to configure all paths corresponding to 'srcEntry' in the 'abilities' field in `scr/main/module.json5` to the white list.
194(2) When the module contains multithreading services: Worker, you need to configure all the paths in the field 'buildOption'-'sourceOption'-'workers' in `build-profiles.json5` to the white list.
195
196#### -enable-export-obfuscation
197
198Enable name and property name obfuscation for directly imported or exported classes or objects. If you use this option, the names of direct imports or exports in the module will be obfuscated, except in the following scenarios:
199
200* The names and property names of classes or objects exported in remote HAR (packages with real paths in oh_modules) will not be obfuscated.
201* Names and property names specified by [keep options](#keep-options) will not be obfuscated.
202* Names in the system API list will not be obfuscated.
203
204**Note**:
205
2061. To obfuscate the property names in imported or exported classes, you need to enable both the `-enable-property-obfuscation` and `-enable-export-obfuscation` options.
2072. When compiling HSP, if the `-enable-export-obfuscation` option is used, the externally exposed interfaces need to be kept in the obfuscation configuration file `obfuscation-rules.txt` in the module.
2083. In the scenario where HAP/HSP/HAR depends on HSP, if the `-enable-export-obfuscation` option is used during compilation, the interface imported from HSP needs to be kept in the obfuscation configuration file `obfuscation-rules.txt` in the module.
209
210     ```
211     // Code example (entry file Index.ets in HSP):
212     export { add, customApiName } from './src/main/ets/utils/Calc'
213
214     // Example of keeping interface name:
215     // obfuscation-rules.txt file configuration in HSP and modules that depend on this HSP:
216    keep-global-name
217    add
218    customApiName
219     ```
220
221#### -compact
222
223Specifies to remove unnecessary blank spaces and all line feeds. If you use this option, all code will be compressed into
224one line.
225**Note**: The stack information in release mode only includes the line number of code, not the column number. Therefore, when the compact is enabled, the specific location of the source code cannot be located based on the line number of stack information.
226
227#### -remove-log
228
229Delete the expressions involving direct calls to console.* statements in the following scenarios:
230
2311. Calls at the toplevel level of a file.
2322. Calls within a block.
2333. Calls within a module.
2344. Calls within a switch statement.
235and the return value of console.* should not be called
236
237#### `-print-namecache` filepath
238
239Specifies to print the name cache that contains the mapping from the old names to new names.
240Note: The namecache.json file will be generated every time the module is fully built, so you should save a copy each time you publish a new version.
241
242#### `-apply-namecache` filepath
243
244Specifies to reuse the given cache file. The old names in the cache will receive the corresponding new names specified in
245the cache. Other names will receive new random short names. This option should be used in incremental obfuscation.
246
247By default, DevEco Studio will keep and update the namecache file in the temporary cache directory and apply the cache for
248incremental compilation.
249Cache directory: build/cache/{...}/release/obfuscation
250
251#### -remove-comments
252
253Remove all comments including single line, multi line and JsDoc comments, in a project except:
254
255* Those names of JsDoc comments above class, function, struct, enum ... in declaration files are in `-keep-comments`.
256**Note**: `-keep-comments` doesn't work for comments in generated source files, which will be deleted.
257
258### Keep options
259
260#### `-keep-property-name` [,identifiers,...]
261
262Specifies property names that you want to keep. For example,
263
264```
265-keep-property-name
266age
267firstName
268lastName
269```
270
271**Note**: This option is avaliable when `-enable-property-obfuscation` is enabled.
272
273`-keep-comments`
274To retain JsDoc comments above elements in declaration files, such as preserving the JsDoc comment above the Human class,
275you can make the following configuration:
276
277```
278-keep-comments
279Human
280```
281
282**Note**:
283
2841. This option is avaliable when `-remove-comments` is enabled.
2852. If the name of an element is obfuscated, the JsDoc comments
286above that element cannot be kept using `-keep-comments`. For example, when you have exportClass in `-keep-comments`,
287you should make sure that the following class will not be obfuscated, or the JsDoc comments above the class will still be removed:
288
289```
290/**
291** @class exportClass
292*/
293export class exportClass {}
294```
295
296**What property names should be kept?**
297
298For safety, we would suggest keeping all property names that are not accessed through dot syntax.
299
300Example:
301
302```
303var obj = {x0: 0, x1: 0, x2: 0};
304for (var i = 0; i <= 2; i++) {
305  console.log(obj['x' + i]);  // x0, x1, x2 should be kept
306}
307
308Object.defineProperty(obj, 'y', {});  // y should be kept
309console.log(obj.y);
310
311obj.s = 0;
312let key = 's';
313console.log(obj[key]);        // s should be kept
314
315obj.u = 0;
316console.log(obj.u);           // u can be safely obfuscated
317
318obj.t = 0;
319console.log(obj['t']);        // t and 't' can be safely obfuscated when `-enable-string-property-obfuscation`, but we suggest keeping t
320
321obj['v'] = 0;
322console.log(obj['v']);        // 'v' can be safely obfuscated when `-enable-string-property-obfuscation`, but we suggest keeping v
323```
324
325In the native API scenario, if in the ets/ts/js file you want to use APIs that are not declared in d.ts file, you need to keep these APIs.
326
327#### `-keep-global-name` [,identifiers,...]
328
329Specifies names that you want to keep in the global scope. For example,
330
331```
332-keep-global-name
333Person
334printPersonName
335```
336
337**What global names should be kept?**
338
339It is known that in javascript the variables in the global scope are properties of `globalThis`. So if in your code
340you access a global variable as a property, then the global name should be kept.
341
342Example:
343
344```
345var a = 0;
346console.log(globalThis.a);  // a should be kept
347
348function foo(){}
349globalThis.foo();           // foo should be kept
350
351var c = 0;
352console.log(c);             // c can be safely obfuscated
353
354function bar(){}
355bar();                      // bar can be safely obfuscated
356
357class MyClass {}
358let d = new MyClass();      // MyClass can be safely obfuscated
359```
360
361#### `-keep-file-name` [,identifiers,...]
362
363Specify the name of files/folders to keep (no need to write the file suffix). for example,
364
365```
366-keep-file-name
367index
368entry
369```
370
371**What file names should be kept?**
372
373```
374const module1 = require('./file1')   // ARKTs doesn't support CommonJS, this path reference should be kept.
375const moduleName = './file2'
376const module2 = import(moduleName)   // dynamic reference cannot identify whether moduleName is a path and should be retained.
377```
378
379#### `-keep-dts` filepath
380
381Specifies to keep names in the given `.d.ts` file. Here filepath can be also a directory. If so, then the names in all
382`d.ts` files under the given directory will be kept.
383If your are building HAR with this option, then the kept names will be merged into the resulting `obfuscation.txt`.
384
385#### `-keep` path
386
387Names(such as variable names, class names, property names, etc.) in the specified path are not obfuscated. This path can be a file or a folder. If it is a folder, the files in the folder and the files in subfolders will not be obfuscated.
388The path only supports relative paths, `./` and `../` are relative to the directory where the obfuscation configuration file is located.
389
390```
391-keep
392./src/main/ets/fileName.ts  // The names in fileName.ts are not obfusated.
393../folder                   // The names of files and subfolders in the folder directory are not obfusated.
394../oh_modules/json5         // The names of all files in the referenced library json5 are not obfusated.
395```
396
397Note: This option does not affect the function of file name obfuscation `-enable-filename-obfuscation`
398
399### Keep options support wildcards
400
401#### Wildcards for name categories
402
403The following options support configuring wildcards for name categories:<br>
404`-keep-property-name`<br>
405`-keep-global-name`<br>
406`-keep-file-name`<br>
407`-keep-comments`<br>
408
409The usage of name categories wildcards is as follows:
410
411| Wildcard | Meaning                              | Example                                            |
412| -------- | ------------------------------------ | -------------------------------------------------- |
413| ?        | Matches any single character         | "AB?" can match "ABC", etc., but cannot match "AB" |
414| \*       | Matches any number of any characters | "*AB*" can match "AB", "aABb", "cAB", "ABc", etc.  |
415
416**Examples**:
417
418Retains all property names starting with 'a':
419
420```
421-keep-property-name
422a*
423```
424
425Retains all single-character property names:
426
427```
428-keep-property-name
429?
430```
431
432Retains all property names:
433
434```
435-keep-property-name
436*
437```
438
439#### Wildcards for path categories
440
441The following options support configuring wildcards for path categories:
442
443`-keep`
444
445The usage of path categories wildcards is as follows:
446
447| Wildcard | Meaning                                                                                                                                             | Example                                                       |
448| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
449| ?        | Matches any single character except path separator '/'                                                                                              | "../a?" can match "../ab", etc., but cannot match "../a/"     |
450| \*       | Matches any number of any characters except path separator '/'                                                                                      | "../a*/c" can match "../ab/c", but cannot match "../ab/d/s/c" |
451| \*\*     | Matches any number of any characters                                                                                                                | "../a**/c" can match "../ab/c", and also "../ab/d/s/c"        |
452| !        | Represents negation and can only be written at the beginning of a path to exclude certain cases that already exist in the user-configured whitelist | "!../a/b/c.ets" means except "../a/b/c.ets"                   |
453
454**Examples**:
455
456Indicates that the c.ets files in all folders in ../a/b/ (excluding subfolders) will not be obfuscated:
457
458```
459-keep
460../a/b/*/c.ets
461```
462
463Indicates that the c.ets files in all folders in ../a/b/ (including subfolders) will not be obfuscated:
464
465```
466-keep
467../a/b/**/c.ets
468```
469
470Indicates that except for the c.ets file, all other files in ../a/b/ will not be obfuscated:
471
472```
473-keep
474../a/b/
475!../a/b/c.ets
476```
477
478Meaningless:
479
480```
481-keep
482!../a/b/c.ets
483```
484
485Indicates that all files will not be obfuscated:
486
487```
488-keep
489*
490```
491
492**Note**:
493
494(1)The above options do not support configuring wildcards '*', '?', '!' for other meanings.
495
496For example:
497
498```
499class A {
500  '*'= 1
501}
502-keep-property-name
503*
504```
505
506It becomes ineffective when you only want to retain the '\*' property.
507
508Here, \* indicates matching any number of any characters, resulting in all property names not being obfuscated, rather than only '\*' not being obfuscated.
509
510(2) The -keep option only allows the use of '/' as the path separator and does not support '\\' or '\\\\'.
511
512### Comments
513
514You can write comments in obfuscation rule file by using `#`. The line begins with `#` is treated as comment.
515For example,
516
517```
518# white list for MainAbility.ets
519-keep-global-name
520MyComponent
521GlobalFunction
522
523-keep-property-name # white list for dynamic property names
524firstName
525lastName
526age
527```
528
529If your are building HAR, comments will not be merged into the resulting `obfuscation.txt`.
530
531### How Arkguard merges rules
532
533Typically there may be serveral rule files in your project. These rule files come from:
534
535* `ruleOptions.files` in main project (Here by main project we mean the project you are building)
536* `consumerFiles` in local dependent libraries
537* `obfuscate.txt` in remote dependent HARs
538When building your main project, all these rules will be merged by the following strategy (in pseudo code):
539
540```
541let `listRules` be the list of all rule files that are mentioned above.
542let finalRule = {
543    disableObfuscation: false,
544    enablePropertyObfuscation: false,
545    enableToplevelObfuscation: false,
546    compact: false,
547    removeLog: false,
548    keepPropertyName: [],
549    keepGlobalName: [],
550    keepDts: [],
551    printNamecache: string,
552    applyNamecache: string
553}
554for each file in `listRules`:
555    for each option in file:
556        switch(option) {
557            case -disable-obfuscation:
558                finalRule.disableObfuscation = true;
559                continue;
560            case -enable-property-obfuscation:
561                finalRule.enablePropertyObfuscation = true;
562                continue;
563            case -enable-toplevel-obfuscation:
564                finalRule.enableToplevelObfuscation = true;
565                continue;
566            case -compact:
567                finalRule.compact = true;
568                continue;
569            case -remove-log:
570                finalRule.removeLog = true;
571                continue;
572            case -print-namecache:
573                finalRule.printNamecache = #{specified path};
574                continue;
575            case -apply-namecache:
576                finalRule.applyNamecache = #{specified path};
577                continue;
578            case -keep-property-name:
579                finalRule.keepPropertyName.push(#{specified names});
580                continue;
581            case -keep-global-name:
582                finalRule.keepGlobalName.push(#{specified names});
583                continue;
584            case -keep-dts:
585                finalRule.keepDts.push(#{specified file path});
586                continue;
587        }
588    end-for
589end-for
590```
591
592The final obfuscation rules are in the object `finalRule`.
593
594If you are building HAR, the resulting `obfuscate.txt` are obtained by merging the rules from `consumerFiles` in main
595project and local dependent libraries, and `obfuscate.txt` in remote dependent HARs. The merging strategy is the same
596except:
597
598* The `-keep-dts` option will be converted to `-keep-global-name` and `-keep-property-name` options in the resulting
599`obfuscate.txt`.
600* The options `-print-namecache` and `apply-namecache` will be omitted and will not appear in the resulting
601`obfuscate.txt`.
602