1# Code Obfuscation
2
3## Overview
4
5Source code obfuscation helps reduce the risk of application hacking as well as the application package size by shortening class names and member names.
6
7Originally, the code obfuscation function was enabled by default in DevEco Studio. For a project developed on the stage model of API version 10 or later, code obfuscation was automatically performed on parameter names and local variable names when the [build mode is release](#usage-description). 
8
9Since DevEco Studio 5.0.3.600, code obfuscation is disabled by default for new projects. If code obfuscation is enabled in the **build-profile.json5** file of the module, four options are enabled by default in the **obfuscation-rules.txt** file: **-enable-property-obfuscation**, **-enable-toplevel-obfuscation**, **-enable-filename-obfuscation**, and **-enable-export-obfuscation**. You can modify the configuration in this file.
10
11### Constraints
12
13* Only the projects developed on the stage model are supported.
14* The build mode of the project is release.
15* The **disable-obfuscation** option is not configured for the module and the HAR on which the module depends.
16
17### Code Obfuscation Scope
18
19In a project, the following files can be obfuscated, and the cache files after obfuscation are stored in **build/[...]/release** in the module directory.
20
21* ArkTS files
22* TS files
23* JS files
24
25## Enabling Code Obfuscation
26
27Code obfuscation has been integrated into the system and can be enabled for use in DevEco Studio.
28
29Currently, only name obfuscation is provided. Other obfuscation capabilities deteriorate performance. You can use code obfuscation to obfuscate the following names:
30
31* Parameter names and local variable names 
32* Top-level scope names 
33* Property names
34* Exported names
35* File names
36
37After code obfuscation is enabled, parameter names and local variable names will be obfuscated by default. No option needs to be configured. Obfuscation of top-level scope name, property names, exported names, and file names may cause runtime errors. You can enable or disable these obfuscation capabilities by configuring obfuscate options.
38
39When a project is created, the following content is automatically generated in the **build-profile.json5** file:
40
41```
42"arkOptions": {
43  "obfuscation": {
44    "ruleOptions": {
45      "enable": true,
46      "files": ["./obfuscation-rules.txt"],
47    }
48  }
49}
50```
51
52When a library is created, the **consumerFiles** field is automatically generated in addition to the preceding content.
53
54```
55"arkOptions": {
56  "obfuscation": {
57    "ruleOptions": {
58      "enable": true,
59      "files": ["./obfuscation-rules.txt"],
60    }
61    "consumerFiles": ["./consumer-rules.txt"]
62  }
63}
64```
65
66If you disable code obfuscation and then want to enable it again, the value of **ruleOptions.enable** must be **true**.
67
68The obfuscation configuration files specified in the **ruleOptions.files** field take effect when the HAP, HSP, or HAR is built.
69
70The obfuscation configuration files specified in the **consumerFiles** field take effect when the module that depends on the library is built. The contents of these obfuscation configuration files are also merged into the **obfuscation.txt** file in the HAR.
71
72During the build of the HAP, HSP, or HAR, the final obfuscation rules are the combination of the **ruleOptions.files** field of the current module, the **consumerFiles** field of the dependent library, and the **obfuscation.txt** file in the dependent HAR.
73
74During HAR build, the **obfuscation.txt** file in the HAR contains the combination of the **consumerFiles** field of the current HAR, the **consumerFiles** field of the dependent library, and the **obfuscation.txt** file in the dependent HAR. No **obfuscation.txt** file is generated during HAP or HSP build. For details about the merge policy, see [Obfuscation Rule Merge Policy](#obfuscation-rule-merge-policy).
75
76**Reminder of Rule Changes**
77
78Since DevEco Studio 5.0.3.600, code obfuscation is disabled by default (**"enable": false**) for a new project. In the **obfuscation-rules.txt** file, **-enable-property-obfuscation**, **-enable-toplevel-obfuscation**, **-enable-filename-obfuscation**, and **-enable-export-obfuscation** are enabled by default. Enabling the four options may cause the application to crash at runtime. You are advised to read [Troubleshooting](#troubleshooting) to rectify the fault.
79
80### Obfuscation Rule Configuration File
81
82During the creation of a project or library, DevEco Studio automatically generates the **obfuscation-rules.txt** and **consumer-rules.txt** files. You can write obfuscation rules into these files or other user-defined files, and then add the file paths in **ruleOptions.files** and **consumerFiles**, as shown in the following example.
83
84```
85"buildOption": {
86  "arkOptions": {
87    "obfuscation": {
88      "ruleOptions": {
89        "enable": true,
90        "files": ["./obfuscation-rules.txt", "./myrules.txt"], // Place myrules.txt in the same directory as the build-profile.json5 file.
91      }
92      "consumerFiles": ["./consumer-rules.txt", "./my-consumer-rules.txt"]
93    }
94  }
95}
96```
97
98## Configuring Obfuscation Rules
99
100There are two types of obfuscation rules: [obfuscate options](#obfuscate-options) and [keep options](#keep-options). The former provides a switch for multiple obfuscation capabilities, such as obfuscation of top-level scope names, property names, and file names. The latter provides the trustlist configuration of various obfuscation capabilities.
101
102**NOTE**
103
104Any modification to the obfuscation configuration takes effect only after a full build of the application.
105
106### Obfuscate Options
107
108#### -disable-obfuscation
109
110Disables code obfuscation. If this option is used, the built HAP, HSP, or HAR is not obfuscated.
111
112#### -enable-property-obfuscation
113
114Enables property obfuscation. If this option is used, all property names except the following are obfuscated:
115
116* Property names of classes and objects that are directly imported or exported by using the **import** or **export** statement. For example, the property name **data** in the following example is not obfuscated.
117
118    ```
119    export class MyClass {
120       data: string;
121    }
122    ```
123
124* Property names in ArkUI components. For example, **message** and **data** in the following example are not obfuscated.
125
126    ```
127    @Component struct MyExample {
128        @State message: string = "hello";
129        data: number[] = [];
130        ...
131    }
132    ```
133
134* Property names specified by [keep options](#keep-options).
135* Property names in the SDK API list. The SDK API list is a name set automatically extracted from the SDK during build. The cache file is **systemApiCache.json**, which is stored in **build/default/cache/{...}/release/obfuscation** in the project directory.
136* String literal property names. For example, **"name"** and **"age"** in the following example are not obfuscated.
137
138    ```
139    let person = {"name": "abc"};
140    person["age"] = 22;
141    ```
142
143    If you want to obfuscate the string literal property name, use the **-enable-string-property-obfuscation** option in addition to the current option, as follows:
144
145    ```
146    -enable-property-obfuscation
147    -enable-string-property-obfuscation
148    ```
149
150    **NOTE** 
151    
152    * If a string literal property name in the code contains special characters, for example, **let obj = {"\n": 123, "": 4, " ": 5}**, you are advised not to use the **-enable-string-property-obfuscation** option because these names may fail to be kept using [keep options](#keep-options). Special characters refer to characters other than lowercase letters a-z, uppercase letters A-Z, digits 0-9, and underscores (_).
153    
154    * The property trustlist of the SDK API list does not contain the string constants used in the declaration file. For example, the string **'ohos.want.action.home'** in the example is not included in the property trustlist.
155
156      ```
157      // Part of the SDK API file @ohos.app.ability.wantConstant:
158      export enum Params {
159        ACTION_HOME = 'ohos.want.action.home'
160      }
161      // Source code example:
162      let params = obj['ohos.want.action.home'];
163      ```
164
165    When the **-enable-string-property-obfuscation** option is used, use the keep option if you want to keep the property names of the SDK API string constants used in the source code, for example, **obj['ohos.want.action.home']**.
166
167#### -enable-toplevel-obfuscation
168
169Enables top-level scope name obfuscation. If this option is used, all names of all top-level scopes except the following are obfuscated:
170
171* Top-level scope names imported or exported using the **import** or **export** statement.
172* Top-level scope names that are not declared in the current file.
173* Top-level scope names specified by [keep options](#keep-options).
174* Top-level scope names in the SDK API list.
175
176#### -enable-filename-obfuscation
177
178Enables file or folder name obfuscation. If this option is used, all file or folder names except the following are obfuscated:
179
180* File or folder names specified by the **main** and **types** fields in the **oh-package.json5** file.
181* File or folder names specified by the **srcEntry** field in the **module.json5** file of the module.
182* File or folder names specified by [-keep-file-name](#keep-options).
183* File or folder names in non-ECMAScript module reference mode. An ECMAScript module example is **import {foo} from './filename'**.
184* File or folder names in non-path reference mode. For example, **json5** in the example **import module from 'json5'** is not obfuscated. 
185
186**NOTE** 
187
188The system loads certain files during application running. For these files, manually configure a trustlist in the [`-keep-file-name`] option to prevent them from being obfuscated. Otherwise, the application may fail to run.
189
190In the following scenarios, you need to manually configure a trustlist: 
191
192* The module contains an ability component. In this case, add all paths configured for **srcEntry** under the **abilities** field in **src/main/module.json5** to the trustlist. 
193* The module contains the multithreading service: Worker. In this case, add all paths under the **buildOption'-'sourceOption'-'workers'** field in **build-profiles.json5** to the trustlist.
194
195**Reminder**
196
197The names of the compilation entry file, ability component file, and worker multithreaded file cannot be obfuscated and have been automatically added to the trustlist in DevEco Studio 5.0.3.500. No manual configuration is required. For other files that cannot be obfuscated, you need to manually configure their names in the trustlist.
198
199#### -enable-export-obfuscation
200
201Enables obfuscation for names of classes or objects that are directly imported or exported and their property names. If this option is used, the names directly imported or exported in the module are obfuscated, except the following:
202
203* Names of classes or objects exported from remote HARs (packages whose real paths are in oh_modules) and their property names.
204* Names and property names specified by [keep options](#keep-options).
205* Names in the SDK API list.
206
207**NOTE**
208
209- To obfuscate property names in imported or exported classes, use both the **-enable-property-obfuscation** and **-enable-export-obfuscation** options. 
210- If the **-enable-export-obfuscation** option is used during HSP build, the externally exposed interfaces must be kept in the **obfuscation-rules.txt** file of the module.
211- During the build of an HAP, an HSP, and an HSP-dependent HAR, if the **-enable-export-obfuscation** option is used, the interfaces imported from the HSP must be kept in the **obfuscation-rules.txt** file in the module. 
212
213    ```
214    // Code example (entry file Index.ets in the HSP):
215    export { add, customApiName } from './src/main/ets/utils/Calc'
216
217    // Example of keeping an interface name:
218    // Configuration of the obfuscation-rules.txt file in the HSP and modules that depend on the HSP:
219    -keep-global-name
220    add
221    customApiName
222    ```
223
224#### -compact
225
226Removes unnecessary spaces and all line feeds. If this option is used, all code is compressed to one line.
227
228**NOTE**
229
230The stack information built in release mode contains the line number of code, but not the column number. Therefore, when the **compact** option is used, the source code cannot be located based on the line number in the stack information.
231
232#### -remove-log
233
234Removes the expressions involving direct calls to the **console.** statement in the following scenarios:
235
236- Calls at the top layer of a file.
237- Calls within a code block.
238- Calls within a module.
239- Calls within a switch statement.
240
241#### -print-namecache *filepath*
242
243Saves the name cache to the specified file path. The name cache contains mappings before and after name obfuscation. 
244
245**NOTE**
246
247A new **namecache.json** file is generated each time the module if fully built. Save a copy of the file each time you publish a new version.
248
249#### -apply-namecache *filepath*
250
251Reuses the specified name cache file. The names will be obfuscated according to the cache mappings. If there is no corresponding name, a new random segment name is used.
252
253This option should be used in incremental build scenarios.
254
255By default, DevEco Studio saves cache files in a temporary cache directory and automatically applies the cache files during incremental build. 
256
257Cache Directory: **build/default/cache/{...}/release/obfuscation**
258
259#### -remove-comments
260
261Removes JsDoc comments from the declaration file generated after compilation. 
262
263**NOTE** 
264
265By default, all comments in the source code file generated after the build are removed and cannot be kept.
266
267You can configure **keep-comments** to keep the JsDoc comments in the declaration file from being obfuscated.
268
269#### -print-kept-names *filepath*
270
271Prints the keep-name list and full trustlist. The **filepath** parameter is optional.
272
273If the **filepath** parameter is not specified, the keep-name list (**keptNames.json**) and full trustlist (**whitelist.json**) are output to the cache directory **build/default/cache/{...}/release/obfuscation** by default.
274
275If the **filepath** parameter is specified, the keep-name list is also exported to the path specified by this parameter. The file path specified must be a relative path, which starts from the directory where the obfuscation configuration file is currently located. The file name extension in the file path must be .json.
276
277The full trustlist (**whitelist.json**) contains all trustlists collected during module compilation. It is classified into the following types:
278
279(1) 'sdk': system APIs.
280
281(2) 'lang': keywords in the language.
282
283(3) 'conf': trustlist in the user-defined keep options.
284
285(4) 'struct': properties in ArkUI structs.
286
287(5) 'export': names and properties exported.
288
289(6) 'strProp': string properties.
290
291(7) 'enum': members in enums (available only during the compilation of the HAR module).
292
293The **keptNames.json** file contains the names that are not obfuscated and the reasons why they are not obfuscated. There are seven reasons: The name is the same as that in the SDK trustlist, language trustlist, user-defined trustlist, struct trustlist, exported name trustlist, or string property trustlist (when string property obfuscation is disabled), or enum trustlist (during HAR module compilation).
294
295
296### Keep Options
297
298#### -keep-property-name *[,identifiers,...]*
299
300Keeps the specified property names from being obfuscated. Name wildcards are supported. An example is as follows.
301
302```
303-keep-property-name
304age
305firstName
306lastName
307```
308
309**NOTE**
310
311This option takes effect when **-enable-property-obfuscation** is used.
312
313What property names should be kept?
314
315For safety, you are advised to keep all properties that are not accessed through dot notation.
316
317Example:
318
319```
320var obj = {x0: 0, x1: 0, x2: 0};
321for (var i = 0; i <= 2; i++) {
322    console.log(obj['x' + i]); // x0, x1, and x2 should be kept.
323}
324
325Object.defineProperty(obj, 'y', {}); // y should be kept.
326console.log(obj.y);
327
328obj.s = 0;
329let key = 's';
330console.log(obj[key]);        // s should be kept.
331
332obj.u = 0;
333console.log(obj.u);           // u can be correctly obfuscated.
334
335obj.t = 0;
336console.log(obj['t']);        // When obfuscation of string literal property names is enabled, both t and 't' can be correctly obfuscated. However, it is recommended that 't' be kept.
337
338obj['v'] = 0;
339console.log(obj['v']);        // When obfuscation of string literal property names is enabled, 'v' can be correctly obfuscated. However, it is recommended that 'v' be kept.
340```
341
342In the case of indirect exports, for example, **export MyClass** and **let a = MyClass; export {a}**, if you do not want to obfuscate property names, use [keep options](#keep-options) to keep them. For property names of directly exported classes or objects, such as **name** and **age** in the following example, if you do not want to obfuscate them, use [keep options](#keep-options) to keep them.
343
344```
345export class MyClass {
346    person = {name: "123", age: 100};
347}
348```
349
350If an API (for example, **foo** in the example) of the .so library needs to be used in the ArkTS/TS/JS file, manually keep the API name.
351
352```
353import testNapi from 'library.so'
354testNapi.foo() // foo should be kept. Example: -keep-property-name foo
355```
356
357Manually keep the fields used in JSON files.
358
359```
360const jsonData = ('./1.json')
361let jsonStr = JSON.parse(jsonData)
362let jsonObj = jsonStr.jsonProperty // jsonProperty should be kept.
363```
364
365Manually keep database-related fields.
366
367```
368const dataToInsert = {  
369  value1: 'example1',   // value1 should be kept.
370};
371```
372
373#### -keep-global-name *[,identifiers,...]*
374
375Keep the top-level scope names from being obfuscated. Name wildcards are supported. Example:
376
377```
378-keep-global-name
379Person
380printPersonName
381```
382
383What top-level scope names should be kept?
384
385In JavaScript, variables in the top-level scope are properties of **globalThis**. If **globalThis** is used to access a global variable in the code, the variable name should be kept.
386
387Example:
388
389```
390var a = 0;
391console.log(globalThis.a); // a should be kept.
392
393function foo(){}
394globalThis.foo();           // foo should be kept.
395
396var c = 0;
397console.log(c);             // c can be correctly obfuscated.
398
399function bar(){}
400bar();                      // bar can be correctly obfuscated.
401
402class MyClass {}
403let d = new MyClass();      // MyClass can be correctly obfuscated.
404```
405
406#### -keep-file-name *[,identifiers,...]*
407
408Keeps the file or folder names from being obfuscated. You do not need to specify the file name extension. Name wildcards are supported. Example:
409
410```
411-keep-file-name
412index
413entry
414```
415
416What file names should be kept?
417
418```
419const module1 = require('./file1')   // ArkTS does not support CommonJS. Therefore, the path reference should be kept.
420const moduleName = './file2'
421const module2 = import(moduleName)    // In dynamic reference mode, it cannot tell whether moduleName is a path. Therefore, the module name should be kept.
422```
423
424#### -keep-comments *[,identifiers,...]*
425
426Keeps the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation from being obfuscated. Name wildcards are supported. For example, to keep the JSDoc comments above the **Human** class in the declaration file, use the following configuration:
427
428```
429-keep-comments
430Human
431```
432
433**NOTE**
434
435- This option takes effect when **-remove-comments** is used.
436- If the classes, functions, namespaces, enums, structs, interfaces, modules, types, and property names in the declaration file generated after compilation are confused, the JsDoc comments above the element cannot be kept using **-keep-comments**. For example, when **exportClass** is configured in **-keep-comments**, if the class name is **exportClass** obfuscated, its JSDoc comments cannot be kept:
437
438```
439/*
440 * @class exportClass
441 */
442export class exportClass {}
443```
444
445#### -keep-dts *filepath*
446
447Keeps the names in the .d.ts file in the specified absolute path from being obfuscated. The file path can be a directory. In this case, the names in all .d.ts files in the specified directory are kept.
448
449#### -keep *filepath*
450
451Keeps all names (such as variable names, class names, and property names) in the specified relative path from being obfuscated. The path can be a file or directory. If the path is a directory, the files in the directory and subdirectories are not obfuscated. 
452
453The path must be a relative path. **./** and **../** are relative to the directory where the obfuscation configuration file is located. Path wildcards are supported.
454
455```
456-keep
457./src/main/ets/fileName.ts   // Names in the fileName.ts file are not obfuscated.
458../folder                    // Names in all the files under the folder directory and its subdirectories are not obfuscated.
459../oh_modules/json5          // Names in all the files in the imported third-party library json5 are not obfuscated.
460```
461
462**NOTE**
463
464This option does not affect the capability provided by the **-enable-filename-obfuscation** option.
465
466#### Wildcards Supported by Keep Options
467
468##### Name Wildcards
469
470The table below lists the name wildcards supported.
471
472| Wildcard| Description                  | Example                                      |
473| ------ | ---------------------- | ------------------------------------------ |
474| ?      | Matches any single character.      | "AB?" matches "ABC", but not "AB".        |
475| \*     | Matches any number of characters.| "\*AB\*" matches "AB", "aABb", "cAB", and "ABc".|
476
477**Use Example**
478
479Keep all property names that start with **a**.
480
481```
482-keep-property-name
483a*
484```
485
486Keep all single-character property names.
487
488```
489-keep-property-name
490?
491```
492
493Keep all property names.
494
495```
496-keep-property-name
497*
498```
499
500##### Path Wildcards
501
502The table below lists the path wildcards supported.
503
504| Wildcard| Description                                                                    | Example                                             |
505| ------ | ------------------------------------------------------------------------ | ------------------------------------------------- |
506| ?     | Matches any single character except the path separator (/).                                     | "../a?" matches "../ab", but not "../a/".        |
507| \*      | Matches any number of characters except the path separator (/).                               | "../a*/c" matches "../ab/c", but not "../ab/d/s/c".|
508| \*\*   | Matches any number of characters.                                                  | "../a**/c" matches "../ab/c" and "../ab/d/s/c". |
509| !      | Negation. It can only be placed at the beginning of a path to exclude a certain case configured in the trustlist.| "!../a/b/c.ets" indicates all paths other than "../a/b/c.ets".          |
510
511**Use Example**
512
513Keep the **c.ets** file in the **../a/b/** directory (excluding subdirectories).
514
515```
516-keep
517../a/b/*/c.ets
518```
519
520Keep the **c.ets** file in the **../a/b/** directory and its subdirectories.
521
522```
523-keep
524../a/b/**/c.ets
525```
526
527Keep all files except the **c.ets** file in the **../a/b/** directory. The exclamation mark (!) cannot be used alone. It can only be used to exclude existing cases in the trustlist.
528
529```
530-keep
531../a/b/
532!../a/b/c.ets
533```
534
535Keep all the files in the **../a/** directory (excluding subdirectories).
536
537```
538-keep
539../a/*
540```
541
542Keep all the files in the **../a/** directory and its subdirectories.
543
544```
545-keep
546../a/**
547```
548
549Keep all the files in the module.
550
551```
552-keep
553./**
554```
555
556**NOTE**
557
558- In these options, the wildcards *, ?, and ! cannot be used for other meanings.
559  Example:
560  
561  ```
562  class A {
563    '*'= 1
564  }
565  
566  -keep-property-name
567  *
568  ```
569
570In this example, * indicates any number of characters, and all property names are kept (not obfuscated). It does not mean that only the * property is kept.
571
572- In the **-keep** option, only the path format / is allowed. The path format \ or \\ is not.
573
574### Comments
575
576You can use **#** to comment out an obfuscation rule file. The line that starts with **#** is treated as a comment.
577
578Example:
579
580```
581# white list for MainAbility.ets
582-keep-global-name
583MyComponent
584GlobalFunction
585
586-keep-property-name # white list for dynamic property names
587firstName
588lastName
589age
590```
591
592During HAR build, comments are not merged into the final **obfuscation.txt** file.
593
594### Obfuscation Rule Merge Policy
595
596A project often has many obfuscation rule files, which are:
597
598* **ruleOptions.files** of the main project (the project being built)
599* File specified by the **consumerFiles** field in the local dependent libraries
600* **obfuscation.txt** file in remote dependent HARs
601
602When the main project is built, the obfuscation rules in these files are merged according to the following policy (in pseudo code):
603
604```
605let `listRules` indicates the list of all obfuscation rule files mentioned above.
606let finalRule = {
607    disableObfuscation: false,
608    enablePropertyObfuscation: false,
609    enableToplevelObfuscation: false,
610    compact: false,
611    removeLog: false,
612    keepPropertyName: [],
613    keepGlobalName: [],
614    keepDts: [],
615    printNamecache: string,
616    applyNamecache: string
617}
618for each file in `listRules`:
619    for each option in file:
620        switch(option) {
621            case -disable-obfuscation:
622                finalRule.disableObfuscation = true;
623                continue;
624            case -enable-property-obfuscation:
625                finalRule.enablePropertyObfuscation = true;
626                continue;
627            case -enable-toplevel-obfuscation:
628                finalRule.enableToplevelObfuscation = true;
629                continue;
630            case -compact:
631                finalRule.compact = true;
632                continue;
633            case -remove-log:
634                finalRule.removeLog = true;
635                continue;
636            case -print-namecache:
637                finalRule.printNamecache = #{specifiedPathName};
638                continue;
639            case -apply-namecache:
640                finalRule.applyNamecache = #{specifiedPathName};
641                continue;
642            case -keep-property-name:
643                finalRule.keepPropertyName.push(#{specifiedName});
644                continue;
645            case -keep-global-name:
646                finalRule.keepGlobalName.push(#{specifiedName});
647                continue;
648            case -keep-dts:
649                finalRule.keepDts.push(#{specifiedPath});
650                continue;
651        }
652    end-for
653end-for
654```
655
656The final obfuscation rule comes from the object **finalRule**.
657
658During HAR build, the final **obfuscation.txt** file comes from the combination of the **consumerFiles** field of the main project and the local dependent libraries, and the **obfuscation.txt** file of the dependent HARs. The merge policy is the same as the preceding one except for the following differences:
659
660* The options **-keep-global-name** and **-keep-property-name** are used instead of **-keep-dts**.
661* The **-print-namecache** and **apply-namecache** options are ignored and will not appear in the final **obfuscation.txt** file.
662
663## Retracing Stack Traces
664
665The function names of an application project after obfuscation are changed. As a result, the stack trace printed during crash is more difficult to understand because it is not completely consistent with the source code. You can use the hstack plugin in DevEco Studio Command Line Tools to restore the source stack trace and analyze problems. The **sourceMap.json** file generated during compilation and the obfuscation name mapping file **nameCache.json** are essential for de-obfuscation. Ensure to back them up locally.
666
667![obfuscation-product](figures/obfuscation-product.png)
668
669## Usage Description
670
671* Currently, custom obfuscation plugins cannot be inserted into the hvigor build process.
672* If a module that depends on an obfuscated HAR enables obfuscation, the HAR will be obfuscated again.
673* To enable the release build mode, select **Product** in the upper right corner of DevEco Studio and set **Build Mode** to **release**.
674
675  ![product-release](figures/product-release.png)
676
677## Appendix
678
679### Mappings Between Obfuscate Options and Minimum SDK Versions
680
681| Obfuscate Option| Description | Minimum SDK Version|
682| ------- | --------- | ------ |
683| -disable-obfuscation         | Disables obfuscation.| 4.0.9.2 |
684| -enable-property-obfuscation | Enables property obfuscation.| 4.0.9.2 |
685| -enable-string-property-obfuscation | Enables obfuscation for string literal property names.| 4.0.9.2 |
686| -enable-toplevel-obfuscation | Enables top-level scope name obfuscation.| 4.0.9.2 |
687| -enable-filename-obfuscation | Enables file or folder name obfuscation for the HAR.<br> Enables file or folder name obfuscation for the HAP/HSP.| 4.1.5.3 <br> 5.0.0.19 |
688| -enable-export-obfuscation   | Enables obfuscation for imported or exported names.| 4.1.5.3 |
689| -compact                     | Removes unnecessary spaces and all line feeds.| 4.0.9.2 |
690| -remove-log                  | Removes the expressions involving direct calls to the **console.** statement in specific scenarios.| 4.0.9.2 |
691| -print-namecache             | Saves the name cache to the specified file path.| 4.0.9.2 |
692| -apply-namecache             | Reuses the specified name cache file.| 4.0.9.2 |
693| -remove-comments             | Removes all comments in the file.| 4.1.5.3 |
694| -keep-property-name          | Keeps property names from being obfuscated.| 4.0.9.2 |
695| -keep-global-name            | Keeps top-level scope names from being obfuscated.| 4.0.9.2 |
696| -keep-file-name              | Keeps file or folder names in the HAR from being obfuscated.<br> Keeps file or folder names in the HAP/HSP from being obfuscated.| 4.1.5.3 <br> 5.0.0.19 |
697| -keep-dts                    | Keeps the names in the .d.ts file in the specified path from being obfuscated.| 4.0.9.2 |
698| -keep-comments               | Keeps the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation from being obfuscated.| 4.1.5.3 |
699| -keep                        | Keeps all names in the specified path from being obfuscated.| 5.0.0.18 |
700| Wildcard                      | The keep options of the name classes and path classes support wildcards.| 5.0.0.24 |
701
702### Viewing the Obfuscation Effect
703
704You can find the obfuscated files, name mapping file, and system API trustlist file in the **build** directory of the build product.
705
706- Obfuscated file directory: build/default/[...]/release/moduleName
707- Directory of the name mapping file and system API trustlist file: build/default/[...]/release/obfuscation
708  - The name mapping file, named **nameCache.json**, records the mappings between source code names and names after obfuscation.
709  - The system API trustlist file, named **systemApiCache.json**, records the APIs and property names that will be kept.
710
711  ![build-product](figures/build-product.png)
712
713### Troubleshooting
714
7151. Configure the **-disable-obfuscation** option in **obfuscation-rules.txt** to disable obfuscation, and check whether the exception is caused by obfuscation.
7162. If the function is abnormal after obfuscation is enabled, read the document to understand the capabilities of obfuscation rules, such as [-enable-property-obfuscation](#keep-options), [-enable-toplevel-obfuscation](#keep-options), [-enable-filename-obfuscation](#keep-options), and [-enable-export-obfuscation](#keep-options), and the syntax scenarios that require the configuration of a [trustlist](#keep-options) to ensure that the application functions properly. The following briefly describes the four keep options that are enabled by default. For details, see the complete description of the corresponding options.
717    1. [-enable-toplevel-obfuscation](#keep-options): keeps top-level scope name from being obfuscated.
718    2. [-enable-property-obfuscation](#keep-options): keeps properties from being obfuscated. You need to use [-keep-property-name](#keep-options) to configure a trustlist for specified property names in scenarios where obfuscation is not allowed, such as network data access, JSON field access, dynamic property access, and .so library API calls.
719    3. [-enable-export-obfuscation](#keep-options): keeps exported names from being obfuscated. Generally, this option is used together with the preceding two options. You need to use [-keep-global-name](#keep-options) to configure a trustlist for exported or imported names in scenarios where external APIs of the module cannot be obfuscated.
720    4. [-enable-filename-obfuscation]: keeps file names from being obfuscated. You need to use [-keep-file-name](#keep-options) to configure a trustlist for file paths and names in scenarios where file paths are dynamically imported or directly loaded at runtime.
7213. If you find a [troubleshooting](#troubleshooting) case similar to your scenario, you can quickly resolve the issue by following the recommended solution.
7224. If no similar case is found, you should identify the issue by examining the configuration functions. If the relevant functions are unnecessary, you can remove the corresponding configuration items.
7235. Analyze application crashes during running as follows:
724    1. Open the application run log or click the Crash dialog box in DevEco Studio to find the crash stack.
725    2. The line number in the crash stack is the line number of the [build product](#viewing-the-obfuscation-effect), and the method name may also be the obfuscated name. Therefore, you are advised to check the build product based on the crash stack, analyze the names that cannot be obfuscated, and add them to the trustlist.
726
727### **FAQs**
728
729#### Errors That May Occur When -enable-property-obfuscation Is Configured
730
731**Case 1**: The error message "Cannot read property 'xxx' of undefined" is reported.
732
733```
734// Before obfuscation
735const jsonData = ('./1.json')
736let jsonStr = JSON.parse(jsonData)
737let jsonObj = jsonStr.jsonProperty
738
739// After obfuscation
740const jsonData = ('./1.json')
741let jsonStr = JSON.parse(jsonData)
742let jsonObj = jsonStr.i
743```
744
745After property obfuscation is enabled, **jsonProperty** is obfuscated as a random character **i**. However, the original name is used in the JSON file, causing the error.
746
747**Solution**: Use the **-keep-property-name** option to add the fields used in JSON files to the trustlist.
748
749**Case 2**: An error message is reported when database-related fields are used and property obfuscation is enabled.
750
751The error message is "table Account has no column named a23 in 'INSET INTO Account(a23)'."
752
753Database fields are used in the code. During obfuscation, the field names in the SQL statements are obfuscated, but the original field names are used in the database, causing the error.
754
755**Solution**: Use the **-keep-property-name** option to add the database fields to the trustlist.
756
757#### Errors That May Occur When -enable-export-obfuscation and -enable-toplevel-obfuscation Are Configured
758
759When the two options are configured, method name confusion in the following scenarios is involved when the main module calls the methods of other modules:
760
761| Main Module| Dependent Module| Confusion of Imported and Exported Names|
762| ------- | ------- | ----------------------------|
763| HAP/HSP | HSP     | The HSP and main module are built independently, and different names are generated after obfuscation. Therefore, a trustlist must be configured for both the HSP and main module.|
764| HAP/HSP | Local HAR| The local HAR is built together with the main module. After obfuscation, the names are the same.|
765| HAP/HSP | Third-party library | The names and properties exported from a third-party library are collected to the trustlist. They are not confused during import and export.|
766
767For the HSP, you must add the methods used by other modules to the trustlist. You must add the same trustlist for the main module. Therefore, you are advised to add the obfuscation file configured with the trustlist (for example, **hsp-white-list.txt**) to the obfuscation configuration item of the module that depends on the obfuscation file, that is, the **files** field shown in the following figure.
768
769![obfuscation-config](figures/obfuscation-config.png)
770
771**Case 1**: When a class is dynamically imported, the class definition is confused, but the class name is not, causing an error.
772
773```
774// Before obfuscation
775export class Test1 {}
776
777let mytest = (await import('./file')).Test1
778
779// After obfuscation
780export class w1 {}
781
782let mytest = (await import('./file')).Test1
783```
784
785The exported class **Test1** is a top-level domain name. When **Test1** is dynamically used, it is a property. Because the **-enable-property-obfuscation** option is not configured, the class name is confused, but the property name is not.
786
787**Solution**: Use the **-keep-global-name** option to add **Test1** to the trustlist.
788
789**Case 2**: For a method in a namespace, the method definition is confused, but the statement that uses the method is not, causing an error.
790
791```
792// Before obfuscation
793export namespace ns1 {
794  export class person1 {}
795}
796
797import {ns1} from './file1'
798let person1 = new ns1.person1()
799
800// After obfuscation
801export namespace a3 {
802  export class b2 {}
803}
804
805import {a3} from './file1'
806let person1 = new a3.person1()
807```
808
809**person1** in the namespace is a top-level class name. When it is called by using **ns1.person1**, **person1** is a property and is not obfuscated because property obfuscation is not enabled.
810
811**Solution:**
812
8131. Configure the **-enable-property-obfuscation** option.
8142. Use the **-keep-global-name** option to add the methods exported from the namespace to the trustlist.
815
816**Case 3**: When declare global is used, a syntax error is reported after obfuscation.
817
818```
819// Before obfuscation
820declare global {
821  var age : string
822}
823
824// After obfuscation
825declare a2 {
826  var b2 : string
827}
828```
829
830The error message "SyntaxError: Unexpected token" is reported.
831
832**Solution**: Use **-keep-global-name** to **add __global** to the trustlist.
833
834#### The **-enable-string-property-obfuscation** option is not configured, but the string literal property name is obfuscated. As a result, the value of the string literal property name is undefined.
835
836```
837person["age"] = 22; // Before obfuscation
838
839person["b"] = 22; // After obfuscation
840```
841
842**Solution:**
843
8441. Check whether **-enable-string-property-obfuscation** is configured for the dependent HAR. If it is configured, the main project will be affected, and you should disable it.
8452. If it must be configured, add the property name to the trustlist.
8463. If it is not configured and the SDK version is earlier than 4.1.5.3, update the SDK.
847
848#### Errors That May Occur When -enable-filename-obfuscation Is Configured
849
850**Case 1**: The error message "Error Failed to get a resolved OhmUrl for 'D:code/MyApplication/f12/library1/pages/d.ets' imported by 'undefined'" is reported.
851
852As shown below, the outer layer of the **library1** module contains a directory named **directory**. When file name obfuscation is enabled, **directory** is obfuscated as **f12**, causing the error indicating that the path is not found.
853
854![directory-offuscation](figures/directory-obfuscation.png)
855
856**Solution:**
857
8581. If the project directory structure and error message are similar, update the SDK to 5.0.0.26 or later.
8592. Use the **-keep-file-name** option to add the directory name **directory** of the module to the trustlist.
860
861**Case 2**: The error message "Cannot find module 'ets/appability/AppAbility' which is application Entry Point" is reported.
862
863The system loads the ability file when the application is running. Therefore, you must manually configure the trustlist to prevent the specified file from being obfuscated.
864
865**Solution**: Use the **-keep-file-name** option to add the path corresponding to the **srcEntry** field in the **src/main/module.json5** file to the trustlist.
866
867```
868-keep-file-name
869appability
870AppAbility
871```
872
873#### Errors That May Occur When -keep-global-name and a Trustlist Are Configured
874
875The error message "Cannot read properties of undefined (reading 'has')" is reported.
876
877**Solution**: Upgrade the SDK to 4.1.6.3 or later.
878