ArkGuard Principles and Capabilities for Source Code Obfuscation
Glossary
| Term | Definition |
|---|---|
| HAP | The Harmony Ability Package (HAP) is the basic unit for installing and running applications. It is a module package generated by packaging code, resources, third-party libraries, and configuration files. |
| HAR | A Harmony Archive (HAR) is a static shared package that enables multiple modules or projects to share code such as ArkUI components and resources. It is created by using a static library. |
| HSP | A Harmony Shared Package (HSP) is a dynamic shared package for sharing code and resources. It is created by using a shared library. |
| Local HAR | HAR module in source code form. |
| Remote HAR | HAR generated after the build. |
| Local HSP | HSP module in source code form. |
| Remote HSP | HSP generated after the build. |
| Third-party library | Libraries developed by third parties and published to the OpenHarmony Third-Party Library Repository. |
| Name obfuscation | Changing class names, method names, variable names, property names, exported variable names and other identifiers to simple, meaningless names. |
Scope of Obfuscation Capabilities
Supported Languages
ArkGuard supports ArkTS, TS, and JS, but not C/C++, JSON, or resource files.
Obfuscation Capabilities
ArkGuard provides name obfuscation, code compression, and comment removal, but does not support advanced features like control stream obfuscation or data obfuscation.
It primarily offers renaming and trustlist configuration for retention.
Limitations of Obfuscation Capabilities
Language Limitations
Source code obfuscation tools vary in type analysis mechanisms, obfuscation strategies, and execution efficiency based on the target language. For example, ProGuard targets strongly-typed languages like Java, where each type has a clear definition source. This feature makes the type relationship tracing and processing in the obfuscation process more accurate, greatly reducing the need for retention rules.
In contrast, ArkGuard targets JS, TS, and ArkTS. Suppose ArkGuard supports configuring a trustlist for specific types. JS supports dynamic modification of objects and functions at runtime, but obfuscation is a static process in the compilation phase. This difference may cause a failure in parsing obfuscated named at runtime, resulting in runtime exceptions. TS and ArkTS use a structural type system, where different named types with the same structure are considered as equivalent types. Therefore, it is difficult to trace the exact source of types. As such, when using ArkGuard, you need to configure trustlists for more syntax scenarios. Moreover, ArkGuard uses a global property retention mechanism that retains all properties with the same name according to the trustlist. It does not support precise retention settings for specific types.
The following is an example:
Assume that ArkGuard allows the configuration of a trustlist for specific types. If class A1 is configured in a trustlist with its property prop1, but prop1 in class A2 is not in the trustlist, then passing an instance of A2 as a parameter to the test function and accessing its properties within the function could lead to issues. Before obfuscation, accessing the prop1 property works as expected. However, after obfuscation, since prop1 in A1 remains unchanged while prop1 in A2 is obfuscated, accessing prop1 in the test function will result in functionality anomalies. ArkGuard does not support precise retention configurations for specific types.
// Before obfuscation:
// example.ts
class A1 {
prop1: string = '';
}
class A2 {
prop1: string = '';
}
function test(input: A1) {
console.info(input.prop1);
}
let a2 = new A2();
a2.prop1 = 'prop a2';
test(a2);
// After obfuscation:
// example.ts
class A1 {
prop1: string = '';
}
class A2 {
a: string = '';
}
function test(input: A1) {
console.info(input.prop1);
}
let a2 = new A2();
a2.a = 'prop a2';
test(a2);
You should be aware of these differences and use unique names to achieve better obfuscation results.
Limited Security Assurance
Similar to other source code obfuscation tools, ArkGuard increases reverse engineering difficulty but cannot prevent it entirely.
You should not rely solely on ArkGuard for security. For higher security requirements, consider application encryption and hardening measures.
Obfuscation Mechanism and Process
The following figure shows a simplified compilation process.

You can enable the obfuscation feature in the build-profile.json5 file of the module so that the source code can be automatically obfuscated during compilation and packaging. For details, see Using ArkGuard for Source Code Obfuscation.
During obfuscation, the tool reads the obfuscation switch. If the switch is enabled, it parses the obfuscation configuration file, merges rules according to the merging strategies, applies obfuscation to intermediate files (generated after syntax conversion), and writes the obfuscated files to the build directory. You can verify the obfuscation effect by examining the output in the build directory.
Before using obfuscation, you are advised to learn about the capabilities of obfuscation options and retention options, and select the appropriate capabilities for your needs.
Obfuscation Options
Summary of Existing Obfuscation Options
| Function | Option |
|---|---|
| Default obfuscation | Enabled after obfuscation is enabled |
| Disabling obfuscation | -disable-obfuscation |
| Enabling obfuscation for property names | -enable-property-obfuscation |
| Enabling obfuscation for string literal property names | -enable-string-property-obfuscation |
| Enabling obfuscation for top-level scope name obfuscation. | -enable-toplevel-obfuscation |
| Enabling obfuscation for imported/exported names | -enable-export-obfuscation |
| Enabling obfuscation for file names | -enable-filename-obfuscation |
| Compressing code | -compact |
| Removing declaration file comments | -remove-comments |
| Removing console.* statement. | -remove-log |
| Printing name caches | -print-namecache |
| Reusing name caches | -apply-namecache |
| Printing unobfuscated names | -print-kept-names |
| Reducing the default language trustlist | -extra-options strip-language-default |
| Reducing the default system API trustlist | -extra-options strip-system-api-args |
| Not retaining the names of modules that are not compiled | -extra-options strip-not-compiled-module-name |
| Retaining declaration file parameters | -keep-parameter-names |
| Merging dependent module options | -enable-lib-obfuscation-options |
| Marking trustlists in source code by comments | -use-keep-in-source |
| Retaining the property name of the object literal | -keep-object-props |
| Deleting a specified method call statement | -remove-nosideeffects-calls |
Default Obfuscation
Default obfuscation takes effect automatically when obfuscation is enabled, and it only obfuscates local variable names and parameter names.
-disable-obfuscation
Disables code obfuscation.
If this option is configured, the default obfuscation capabilities (obfuscating only local variables and parameter names) and all configured obfuscation and retention options become invalid.
-enable-property-obfuscation
NOTE
After this option is enabled, if you need to manually configure the trustlist, add the property name to the trustlist.
Enables property name obfuscation. The effect is as follows:
// Before obfuscation:
class TestA {
static prop1: number = 0;
}
TestA.prop1;
// After obfuscation:
class TestA {
static i: number = 0;
}
TestA.i;
If this option is configured, all property names except the following are obfuscated:
-
Property names of classes or objects that are directly imported or exported by using
import/exportin case that the-enable-export-obfuscationoption is not configured. For example, the property namedata1in the following example is not obfuscated.// example.ts export class MyClass01 { data1: string; } -
Property names in ArkUI components. For example,
messageanddatain the following example are not obfuscated.// example.ets @Component struct MyExample { @State message: string = "hello"; data: number[] = []; // ... build() { } } -
Property names specified in retention options.
-
Property names in the SDK API list. The SDK API list is a set of names automatically extracted from the SDK during build. Its cache file is systemApiCache.json, which is stored in /build/default/cache/{...}/release/obfuscation in the project directory.
-
String literal property names remain unobfuscated, and property names with the same name are also not obfuscated. For example,
exampleNameandexampleAgein the following example are not obfuscated.// Before obfuscation: // example.ts let person = {"exampleName": "abc"}; person["exampleAge"] = 22;let person1 = {exampleName: "aaa"}; let name = person1.exampleName; -
Annotation member names. For example,
authorNameandrevisionin the following example are not obfuscated.@interface MyAnnotation1 { authorName: string; revision: number = 1; }
-enable-string-property-obfuscation
To obfuscate string literal property names, you must use this option together with -enable-property-obfuscation. Example:
-enable-property-obfuscation
-enable-string-property-obfuscation
According to the preceding configuration, the obfuscation effect of exampleName and exampleAge is as follows:
// Before obfuscation:
// example.ts
let person = {"exampleName": "abc"};
person["exampleAge"] = 22;
// After obfuscation:
// example.ts
let person = {"a": "abc"};
person["b"] = 22;
NOTE
-
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-obfuscationoption because these names may fail to be retained using -keep-property-name. Special characters refer to characters other than lowercase letters a-z, uppercase letters A-Z, digits 0-9, and underscores (_). -
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.
// Part of the SDK API file @ohos.app.ability.wantConstant: export enum Params { ACTION_HOME = 'ohos.want.action.home' } // Source code example: const obj1: Record<string, string> = { 'ohos.want.action.home': 'value' } let params = obj1['ohos.want.action.home'];Therefore, after
-enable-string-property-obfuscationis enabled, if you want to retain the properties of SDK API string constants used in the code, for example, obj['ohos.want.action.home'], you can use the -keep-property-name option.
-enable-toplevel-obfuscation
NOTE
After this option is enabled, if you need to manually configure the trustlist, add the top-level scope name to the trustlist.
Enables obfuscation of top-level scope names. The effect is as follows:
// Before obfuscation:
let count = 0;
// After obfuscation:
let s = 0;
If this option is configured, the names of all top-level scopes except the following are obfuscated:
- Names that are directly imported or exported by using
import/exportin case that the-enable-export-obfuscationoption is not configured. - Top-level scope names that are not declared in the current file.
- Top-level scope names specified by retention options.
- Top-level scope names in the SDK API list.
-enable-export-obfuscation
Enables obfuscation for imported/exported names. The effect is as follows:
// Before obfuscation:
namespace ns {
export type customT = string;
}
// After obfuscation:
namespace ns {
export type h = string;
}
If this option is configured, only names imported/exported in non-top-level scopes will be obfuscated. To obfuscate names imported/exported in the top-level scope, use this option with -enable-toplevel-obfuscation. To obfuscate imported or exported property names, use this option -enable-property-obfuscation. Note the following special scenarios:
- Names exported from remote HARs (packages whose real paths are in oh_modules) and their property names are not obfuscated.
- Names and property names specified by retention options are not obfuscated.
- Names in the SDK API list are not obfuscated.
-enable-filename-obfuscation
NOTE
After this option is enabled, if you need to manually configure the trustlist, add the corresponding folder name or file name to the trustlist.
Enables obfuscation of file/folder names. The effect is as follows:
// test1/test2.ts
export function foo () {}
// example.ts
// Before obfuscation:
import * as m from '../test1/test2';
import { foo } from '../test1/test2';
// ...
m.foo();
foo();
async function func1() {
const modules = await import('../test1/test2');
const result = modules.foo();
}
// example.ts
// After obfuscation:
import * as m from "@normalized:N&&&entry/src/main/ets/c/d&";
import { foo } from "@normalized:N&&&entry/src/main/ets/c/d&";
m.foo();
foo();
async function func() {
const f = await import("@normalized:N&&&entry/src/main/ets/c/d&");
const g = f.foo();
}
If this option is configured, all file names and folder names except the following are obfuscated:
- File or folder names specified by the main and types fields in the oh-package.json5 file.
- File or folder names specified by the srcEntry field in the module.json5 file of the module.
- File or folder names specified by -keep-file-name.
- File or folder names in non-ECMAScript module reference mode (for example,
const module = require('./module')). - File or folder names in non-path reference mode. For example,
json5in the exampleimport module from 'json5'is not obfuscated.
NOTE
For files that the system needs to load files during application running, manually configure them into a trustlist using the -keep-file-name option. Otherwise, the application may fail to run.
The 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 or later. No manual configuration is required. For other files that cannot be obfuscated, you need to manually configure their names in the trustlist.
-compact
Removes spaces and all newline characters that do not participate in the syntax structure and do not affect program execution.
If this option is configured, all code is compressed to one line. The effect is as follows:
// Before obfuscation:
class TestA {
static prop1: number = 0;
}
TestA.prop1;
// After obfuscation:
class TestA { static prop1: number = 0; } TestA.prop1;
NOTE
The 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.
-remove-comments
Removes JsDoc comments from the declaration file generated after compilation. The effect is as follows:
Before obfuscation:
/**
* @todo
*/
declare let count1: number;
After obfuscation:
declare let count: number;
You can use -keep-comments to retain the JsDoc comments in the declaration file.
NOTE
By default, all comments in the source code file generated after the compilation are removed and cannot be retained.
-remove-log
Removes calls to console.* statements, provided the return value is not used. The effect is as follows:
// Before obfuscation:
function add(a: number, b: number) {
console.info("result", a + b);
return a + b;
}
// After obfuscation:
function add(a: number, b: number) {
return a + b;
}
If this option is configured, the console.* statements in the following scenarios are removed:
-
Calls at the top layer of a file. Example:
console.info("in tolevel"); -
Calls within a code block. Example:
function foo1() { console.info('in block'); } -
Calls with a module or namespace. Example:
// example.ts namespace ns { console.info('in ns'); } -
Calls within a switch statement. Example:
function getDayName(day: number): string { switch (day) { case 1: console.info("Matched case 1: Monday"); return "Monday"; case 2: console.info("Matched case 2: Tuesday"); return "Tuesday"; default: console.error("No matching case for day:", day); return "Invalid date"; } }
-print-namecache
Saves the name cache to the specified file path. The name cache contains the mappings of names before and after obfuscation. The filepath parameter is mandatory. It supports relative and absolute paths. For a relative path, the start point is the current directory of the obfuscation configuration file. The file name extension in filepath must be .json.
Example:
-print-namecache
./customCache/nameCache.json
NOTE
A new namecache.json file is generated each time the module if fully built. Therefore, save a copy of the file each time you publish a new version.
-apply-namecache
Reuses a name cache file in the specified file path. The filepath parameter is mandatory. It supports relative and absolute paths. For a relative path, the start point is the current directory of the obfuscation configuration file. The file name extension in filepath must be .json.
This option applies to incremental build. After this option is enabled, names are obfuscated based on the cache mapping. If no matching cache is found, the name is obfuscated as a new random name.
Example:
-apply-namecache
./customCache/nameCache.json
By default, DevEco Studio saves cache files in a temporary cache directory and automatically applies the cache files during incremental build. Default cache directory: build/default/cache/{...}/release/obfuscation
-print-kept-names
Prints the unobfuscated list and full trustlist to the specified file path. The filepath parameter is optional. It supports relative paths, with the start point being the current directory of the obfuscation configuration file. The file name extension in filepath must be .json.
From API version 18, the unobfuscated list and full trustlist can be output.
If the filepath parameter is not specified, the unobfuscated list (keptNames.json) and full trustlist (whitelist.json) are output to the cache directory build/default/cache/{...}/release/obfuscation by default.
If the filepath parameter is specified, the unobfuscated list is output to the directory specified by filepath.
The full trustlist collected during a full build is classified into the following types:
(1) 'sdk': system APIs.
(2) 'lang': keywords in the language.
(3) 'conf': trustlist in the user-defined retention options.
(4) 'struct': properties in ArkUI structs.
(5) 'exported': names and properties exported.
(6) 'strProp': string properties.
(7) 'enum': enum members.
The 'sdk' trustlist is exported to the systemApiCache.json file in the build/default/cache/{...}/release/obfuscation/ directory, and other trustlists are exported to the whitelist.json file.
The keptNames.json file contains unobfuscated names and their reasons. Unobfuscated names are those that have the same name as the SDK trustlist, language trustlist, user-defined trustlist, struct trustlist, exported name trustlist, or string property trustlist (when string literal property name obfuscation is disabled), or enum trustlist.
NOTE
-
During HAR module compilation with property name obfuscation enabled, enum member names are collected into the 'enum' trustlist.
Example:
enum Test1 { member1, member2 }The 'enum' trustlist includes names such as ['member1', 'member2']. This requirement stems from the fact that, in earlier HAR module versions, the compilation process produced JS files. In these JS files, enums are represented as immediately invoked functions, with enum members expressed as string properties and constants. To maintain proper functionality during property name obfuscation, these enum member names must be added to the trustlist. This practice continues to be applied when compiling the latest bytecode HAR modules.
-
During HAP/HSP/bytecode HAR module compilation with property name obfuscation enabled, variable names in initialization expressions of enum members are collected into the 'enum' trustlist.
Example:
// example.ts let outdoor = 1; enum Test2 { member1, member2 = outdoor + member1 + 2 }In the case of HAP/HSP module compilation, the content of the 'enum' trustlist is ['outdoor', 'member1']. In the case of bytecode HAR module compilation, the content is ['outdoor', 'member1', 'member2'].
-extra-options strip-language-default
By default, the default language trustlist contains the names of APIs related to DOM, WebWorker, and ScriptHost in the TS system interfaces, as well as the names of Web APIs. If property names in the source code match these names, they will be retained.
To obfuscate these parts of the code, configure the -extra-options strip-language-default option.
This option is supported since API version 18.
You can determine the specific reduction range of APIs retained by default as follows:
Enable the -print-kept-names option and compare the differences in the lang field of the whitelist.json file when the -extra-options strip-language-default option is enabled and disabled. The difference represents the specific reduction range of the default language trustlist.
-extra-options strip-system-api-args
By default, the system API trustlist contains local variable names in system APIs and is effective for local variables in your source code by default. If property names in the source code match local variables in system APIs or if local variables in the source code match the system API trustlist, these property names and local variables will be retained.
If you need to obfuscate the code, configure the -extra-options strip-system-api-args option.
This option is supported since API version 18.
The specific content of the system API trustlist can be viewed in the systemApiCache.json file through the ReservedLocalNames, ReservedPropertyNames, and ReservedGlobalNames fields. This file, located in the directory build/default/cache/{...}/release/obfuscation, records the interface and property names in the SDK, and source code with matching names will not be obfuscated.
You can determine the specific reduction range of the system API trustlist as follows:
Compare the differences in the ReservedLocalNames and ReservedPropertyNames fields of the systemApiCache.json file when the -extra-options strip-system-api-args option is enabled and disabled. The difference represents the specific reduction range of the system API trustlist. However, the content of the ReservedGlobalNames field will not change.
-extra-options strip-not-compiled-module-name
By default, the current obfuscation trustlist contains all module names in the project. If file names in the source code match module names, the obfuscation tool will retain these file names.
You can configure the -extra-options strip-not-compiled-module-name option to obfuscate files with the same name as the modules that are not involved in compilation.
This option is supported since API version 22.
When this option is enabled, only the names of compiled modules and their directly or indirectly dependent local source code Har modules are added to the obfuscation trustlist. All other module names are not retained.
How to use -extra-options
Add the -extra-options prefix and options in the obfuscation configuration file, with no additional content in between. You can enable either one option or multiple options, as shown in the following examples:
-
Use the -extra-options prefix to enable a single option in either of the following ways:
# Method 1 -extra-options strip-language-default # Method 2 -extra-options strip-language-default -
Use the**-extra-options** prefix to enable multiple options in any of the following ways:
# Method 1 -extra-options strip-language-default, strip-system-api-args, strip-not-compiled-module-name # Method 2 -extra-options strip-language-default strip-system-api-args strip-not-compiled-module-name # Method 3 -extra-options strip-language-default strip-system-api-args strip-not-compiled-module-name # Method 4 -extra-options strip-language-default strip-system-api-args strip-not-compiled-module-name # Method 5 -extra-options strip-language-default -extra-options strip-system-api-args -extra-options strip-not-compiled-module-name
-keep-parameter-names
From API version 18, parameter names in declaration files for exported APIs can be retained. The effect is as follows:
- For functions and class member methods, if the function or method name is not confused, their parameter names are retained.
- For class constructors, if the class name is not obfuscated, their parameter names in the constructors are retained.
NOTE
-
Parameter names that are not in the preceding scenarios (such as anonymous functions) will still be obfuscated.
-
Parameter names in source code files will be obfuscated regardless of this option.
-enable-lib-obfuscation-options
Merges obfuscation options of dependent modules into the obfuscation configuration of the current module.
This option is supported since API version 18.
Obfuscation configuration includes obfuscation options and retention options.
- By default, the effective obfuscation configuration is the merged result of the current module's obfuscation configuration and the dependent modules' retention options.
- When this option is configured, the effective obfuscation configuration is the merged result of the current module's obfuscation configuration and the dependent modules' obfuscation configuration.
For details about the merging logic, see Obfuscation Rule Merging Strategies.
-use-keep-in-source
Since API version 19, the following two types of annotations can be added to the trustlist in the .ts and .ets source code, but cannot be used in the declaration file.
// @KeepSymbol: This annotation is used to mark names that should be retained. It is usually placed on the line above the relevant code to ensure that the name is not obfuscated when the code is compiled.
// @KeepAsConsumer: This annotation is used to mark names that should be retained. It is usually placed on the line above the relevant code to ensure that the name is not obfuscated when the code is compiled. In HAR/HSP modules, names marked with @KeepAsConsumer are also listed in the obfuscation.txt file. In HAP modules, @KeepAsConsumer works exactly like @KeepSymbol.
NOTE
Both types of markings are comments and the slashes (//) should not be removed.
The examples below use // @KeepSymbol, but // @KeepAsConsumer can be used in the same way for the same purposes.
Class
You can mark the following elements in a class:
- Class declarations
- Constructors
- Fields and methods
Example
// Retain the class name and all member names.
// @KeepSymbol
class MyClass02 {
prop01: string = "prop"; // MyClass02 and prop01 are not obfuscated.
}
// Use the constructor to retain the class name.
class MyClass03 {
prop02: string = "prop";
// @KeepSymbol
constructor() {}; // MyClass03 is not obfuscated.
}
// Retain the class name and specified field and method names. MyClass04, prop03_1, and method03_2 in the class are not obfuscated.
class MyClass04 {
// @KeepSymbol
prop03_1: string = "prop";
prop03_2: number = 1;
constructor() {};
method03_1(): void {};
// @KeepSymbol
method03_2(): void {};
}
You can mark the following elements in an interface:
- Interface declarations
- Fields and methods
Example
// Retain the interface name and all member names. MyInterface01, name01, and foo01 are not obfuscated.
// @KeepSymbol
interface MyInterface01 {
name01: string;
foo01(): void;
}
// Retain the interface name and specified field and method names. MyInterface02 and name02 are not obfuscated.
interface MyInterface02 {
// @KeepSymbol
name02: string;
foo02(): void;
}
Enumeration
You can mark the following elements in an enum:
- Enum declarations
- Enum members
Example
// Retain the enum name and all member names. Color01, RED01, and BLUE01 are not obfuscated.
// @KeepSymbol
enum Color01 {
RED01,
BLUE01
}
// Retain the specified enum member name.
enum Color02 {
RED02,
// @KeepSymbol
BLUE02 // Color02 and BLUE02 are not obfuscated.
}
Function
Function names can be marked.
Example
// Retain the function name. MyAdd is not obfuscated.
// @KeepSymbol
function MyAdd(a: number, b:number): number {
return a + b;
}
Namespace
Namespace names can be marked.
Example
// Retain the namespace name and the member names directly exported internally. MyNameSpace and foo are not obfuscated.
// @KeepSymbol
namespace MyNameSpace {
export function foo(){};
function bar(){};
}
Global Variable
Currently, only global variables can be marked. Local variables cannot be marked.
Example
// Retain the marked variable name. myVal is not obfuscated.
// @KeepSymbol
const myVal = 1;
Comment
Currently, only the marking and retention of annotation declarations are supported. Marking annotation members is invalid, and the annotation members themselves are not obfuscated.
Starting from API version 20, marking annotation declarations is supported.
Example
// Retain the marked annotation declaration. MyAnnotation will not be obfuscated.
// @KeepSymbol
@interface MyAnnotation2 {
// Marking annotation members is invalid; authorName will not be added to the trustlist.
// @KeepSymbol
authorName: string;
revision: number = 1;
}
Trustlist Addition Rules
Marked names are added to the obfuscation trustlist based on the following rules. Names kept by KeepAsConsumer are also recorded in the obfuscation.txt file.
-
If a name is at the top level or directly exported, it goes into -keep-global-name.
-
If a name is directly exported, it also goes into -keep-property-name.
-
If a name is a property, it goes into -keep-property-name.
-
Local variable names are not added to the trustlist (they are not kept).
Example
// @KeepAsConsumer
export class MyClass05 {
prop01: string = "prop";
}
In the preceding example, MyClass is added to -keep-global-name and -keep-property-name, and prop01 is added to -keep-property-name. The rule is also written into the obfuscation.txt file.
Scenarios Not Supported by -use-keep-in-source
String properties, numeric properties, and computed properties are not supported.
Example
// example.ts
const myMethodName = "myMethod";
// 11, aa, and myMethod are not added to the trustlist.
class MyClass06 {
// @KeepSymbol
11:11;
// @KeepSymbol
'aa':'aa';
// @KeepSymbol
[myMethodName](){}
}
// RED is not added to the trustlist.
enum MyEnum {
// @KeepSymbol
'RED',
BLUE
}
-keep-object-props
Since API version 23, the -keep-object-props configuration option can be used to retain the property names and string property names in object literals. The usage is as follows:
-
If only property obfuscation (-enable-property-obfuscation) is enabled and the -keep-object-props option is selected, the property names in the object literals will be collected to the trustlist and will not be obfuscated.
-
If both property obfuscation (-enable-property-obfuscation) and string property obfuscation (-enable-string-property-obfuscation) are enabled and the -keep-object-props option is selected, the property names and string property names in the object literals will be collected to the trustlist and will not be obfuscated.
NOTE
- The -keep-object-props option takes effect only when property obfuscation is enabled or both property obfuscation and string property obfuscation are enabled.
Supported Scenarios
The property names of object literals and string property names can be retained.
Example
// example.ts
const propertyObj = {
propertyKey1: 'value',
propertyKey2: {
propertyKey3: 'value'
}
};
const stringPropertyObj = {
'stringPropertyKey1': 'Alice',
'stringPropertyKey2': {
'stringPropertyKey3': 'additional data'
}
};
-
If property obfuscation is enabled and the -keep-object-props option is configured, the property names in the object literal will not be obfuscated.
The obfuscation configuration option file obfuscation-rules.txt is as follows:
-keep-object-props -enable-property-obfuscationAfter the obfuscation options in the obfuscation-rules.txt configuration file are enabled, the property names propertyKey1, propertyKey2, and propertyKey3 in the sample code are collected to the trustlist and will not be obfuscated.
-
When property obfuscation and string property obfuscation are enabled, if the -keep-object-props option is configured, the property names and string property names in the object literal will not be obfuscated.
The obfuscation configuration option file obfuscation-rules.txt is as follows:
-keep-object-props -enable-property-obfuscation -enable-string-property-obfuscationAfter the obfuscation option of the obfuscation-rules.txt configuration file is enabled, the property names propertyKey1, propertyKey2, and propertyKey3 as well as the string property names stringPropertyKey1, stringPropertyKey2, and stringPropertyKey3 in the sample code are collected to the trustlist and will not be obfuscated.
Unsupported Scenarios
Non-object literal property names are not supported.
Example
// example.ts
// Scenarios where -keep-object-props does not take effect: typeLiteral1, typeLiteral2, typeLiteral3, typeLiteral4, and typeLiteral5 are not properties in object literals. When property obfuscation is enabled, or both property obfuscation and string property obfuscation are enabled, these properties will still be obfuscated even if the -keep-object-props option is enabled.
interface TypeLiteralDemo {
typeLiteral1: {
typeLiteral2: number,
'typeLiteral3': string
},
typeLiteral4: string,
'typeLiteral5': string
}
// Scenarios where -keep-object-props does not take effect: Symbol.iterator, dynamic and Property are complex computing properties. When property obfuscation is enabled, or both property obfuscation and string property obfuscation are enabled, these properties will not be obfuscated whether the -keep-object-props option is enabled or not.
const complexComputedPropertyObj = {
[Symbol.iterator]: 'value',
["dynamic" + "Property"]: 'value'
}
-remove-nosideeffects-calls
Since API version 23, a method call with a specified name can be deleted. The return value of the method call must be unused. This feature is applicable to scenarios such as deleting custom log method calls.
The supported method call patterns are as follows:
- Direct call: method, matching method().
- Dot call: A.B, matching A.B().
- Bracket call: A["B"], matching A["B"]().
- Nested call: A.B["method"], matching A.B["method"]().
- Wildcard matching: Pattern matching is performed using name wildcards, for example, *.log, matching log() of any object.
NOTE
-
This option does not analyze side effects within the method when deleting method calls. You must ensure that removing the method call does not impact application functionalities.
-
The configuration item must exactly match the full name at the actual call in the source code, rather than the name of the declaration.
For example, the configuration item
MyLog.debugin the following example does not match the name of the call, soLog.debug()will not be deleted.// obfuscation-rules.txt or consumer-rules.txt: -remove-nosideeffects-calls MyLog.debug// a.ts export class MyLog { public static debug(message: string) { console.info(message); } } // b.ts import { MyLog as Log } from './a' Log.debug("this is alias"); -
Configuration items can be separated by commas (,), spaces, or line breaks.
Example
In the obfuscation configuration file obfuscation-rules.txt or consumer-rules.txt:
-remove-nosideeffects-calls
logger
Log.debug*
example["log"].info
According to the preceding configuration, the method call statements in the following scenarios will be deleted:
-
Calls at the top layer of a file.
Example:
function logger(msg: string) { console.info(msg); } logger("in top level"); // After obfuscation, the method call is deleted. -
Calls within a code block.
Example:
class Log { public static debugBlock(msg: string) { console.info(msg); } } function foo() { Log.debugBlock("in block"); // After obfuscation, the method call is deleted. } -
Calls with a module or namespace.
Example:
// example.ts class Log { public static debugNamespace(msg: string) { console.info(msg); } } namespace ns { Log.debugNamespace("in namespace"); // After obfuscation, the method call is deleted. } -
Calls within a switch statement.
Example:
interface Logger { info: (msg: string, res?: number) => void; } const logFunc: Logger = { info: (msg: string, res?: number): void => { console.info(msg, res); } } const example: Record<string, Logger> = { ["log"]: logFunc } function getDayName(day: number): string { switch (day) { case 1: example["log"].info("Matched case 1: Monday"); // After obfuscation, the method call is deleted. return "Monday"; case 2: example["log"].info("Matched case 2: Tuesday"); // After obfuscation, the method call is deleted. return "Tuesday"; default: example["log"].info("No matching case for day:", day); // After obfuscation, the method call is deleted. return "Invalid date"; } }
Retention Options
After obfuscation is enabled, methods, properties, and paths in the code are obfuscated. If methods, properties, or paths that are not obfuscated are accessed during runtime, the functionalities may be unavailable. Therefore, you need to configure retention options based on different scenarios.
When checking the scenarios and configuration fields, you are advised to use obfuscation for code hardening to quickly identify the retention options and trustlist fields to be configured.
Summary of Existing Retention Options
| Function | Option |
|---|---|
| Retaining specified property names | -keep-property-name |
| Retaining specified top-level scope names or imported/exported element names | -keep-global-name |
| Retaining specified file/folder names | -keep-file-name |
| Retaining specified comments | -keep-comments |
| Retaining all names in specified declaration files | -keep-dts |
| Retaining all names in specified source code files | -keep |
-keep-property-name
Retains the specified property names. Name wildcards are supported. The following configuration is used to retain properties named firstName and lastName:
-keep-property-name
firstName
lastName
NOTE
-
This option takes effect when
-enable-property-obfuscationis used. -
The property trustlist applies globally. That is, if multiple properties with the same name exist in the code, they will not be confused as long as they match the names in the trustlist configured in
-keep-property-name.
Property Names Requiring Manual Trustlist Configuration
- If object properties are defined via string concatenation, variable access, or the
definePropertymethod within the code, these property names should be retained. Example:
// example.js
var obj = {x0: '0', x1: '1', x2: '2'};
for (var i = 0; i <= 2; i++) {
console.info(obj['x' + i]); // x0, x1, and x2 should be retained.
}
Object.defineProperty(obj, 'y', {}); // y should be retained.
Object.getOwnPropertyDescriptor(obj, 'y'); // y should be retained.
console.info(obj.y);
obj.s1 = 'a';
let key = 's1';
console.info(obj[key]); // The variable value s1 corresponding to key should be retained.
obj.t1 = 'b';
console.info(obj['t' + '1']); // t1 should be retained.
For the following string literal property calls, you can choose to retain them.
// Obfuscation configuration:
// -enable-property-obfuscation
// -enable-string-property-obfuscation
// example.ts
var obj2 = {t:'1', m:'2'};
obj2.t = 'a';
console.info(obj2['t']); // 't' will be correctly confused, and t can be retained.
obj2['m'] = 'b';
console.info(obj2['m']); // 'm' will be correctly confused, and m can be retained.
- If an issue occurs after obfuscation in an indirect or direct export of a class or object property, you can use -keep-property-name to retain the property name.
// Indirectly export MyClass07.
class MyClass07 {
greet() {}
}
let alias = new MyClass07();
export { alias };
// Directly export MyClass08.
export class MyClass08 {
exampleName: 'jack'
exampleAge: 100
}
- If you want to use an API (for example, add in the example) of the .so library in the ArkTS/TS/JS file, manually retain the API name.
// src/main/cpp/types/libentry/Index.d.ts
export const addNum: (a: number, b: number) => number;
// example.ets
import testNapi from 'libentry.so';
testNapi.addNum(2, 3); // addNum needs to be retained. Example: -keep-property-name addNum
- Fields used in JSON parsing and object serialization should be retained.
{
"jsonProperty": "value",
"otherProperty": "value2"
}
import jsonData from './test.json';
// ...
let jsonProp = jsonData.jsonProperty; // jsonProperty should be retained.
class jsonTest {
prop1: string = '';
prop2: number = 0
}
let obj = new jsonTest();
const jsonStr = JSON.stringify(obj); // prop1 and prop2 will be obfuscated and should be retained.
- Database-related fields should be manually retained. For example, properties in the database key-value pair type (ValuesBucket):
import { ValuesBucket } from '@kit.ArkData';
// ...
const valueBucket: ValuesBucket = {
ID1: 'ID1', // ID1 should be retained.
NAME1: 'jack', // NAME1 should be retained.
AGE1: 20, // AGE1 should be retained.
SALARY1: 100 // SALARY1 should be retained.
}
- When custom decorators are used on member variables, member methods, or parameters in the source code, and the intermediate product of source code compilation is a JS file (for example, compiling release-mode source code HAR or source code containing @ts-ignore or @ts-nocheck), the names of these member variables or member methods should be retained. This is because the names of these member variables/methods are hardcoded as string literals during conversion from TS syntax to standard JS syntax.
Example:
function CustomDecorator(target: Object, propertyKey: string) {}
function MethodDecorator(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {}
function ParamDecorator(target: Object, propertyKey: string, parameterIndex: number) {}
class A {
// 1. Member variable decorator
@CustomDecorator
propertyName1: string = "" // propertyName1 should be retained.
// 2. Member method decorator
@MethodDecorator
methodName1() {} // methodName1 should be retained.
// 3. Method parameter decorator
methodName2(@ParamDecorator param: string): void {} // methodName2 should be retained.
}
- Data request-related fields (such as the fields transferred to the data requester) should be manually retained.
// example.ets
import { UIAbility } from '@kit.AbilityKit';
import { http } from '@kit.NetworkKit';
// ...
export default class EntryAbility extends UIAbility {
onForeground(): void {
let httpRequest = http.createHttp();
httpRequest.request('https://www.example/Login',
{
method: http.RequestMethod.POST,
header: { 'Content-Type': 'application/json' },
extraData: { usernameTest: 'test1', passwordTest: 'test2'}, // usernameTest and passwordTest should be retained.
})
}
}
-keep-global-name
Retains the specified top-level scope names and imported/exported element names. Name wildcards are supported. The configuration procedure is as follows:
-keep-global-name
Person
printPersonName
Names exported from the namespace can also be retained using the -keep-global-name option. The following is an example:
// example.ts
export namespace Ns {
export const myAge = 18 // -keep-global-name myAge: retains variable myAge.
export function myFunc() {} // -keep-global-name myFunc: retains function myFunc.
}
NOTE
-
This option takes effect when
-enable-toplevel-obfuscationor-enable-export-obfuscationis used. -
The trustlist specified by
-keep-global-nameapplies globally. That is, if multiple top-level scope names or exported names exist in the code, they will not be confused as long as they match the names in the trustlist configured in-keep-global-name.
Top-level Scopes Requiring Manual Trustlist Configuration
When importing API names from .so libraries using named imports, if both -enable-toplevel-obfuscation and -enable-export-obfuscation are configured, the API names should be manually retained.
// src/main/cpp/types/libentry/Index.d.ts
declare function testNapi2(): void;
declare function testNapi3(): void;
// example.ets
import { testNapi2, testNapi3 as myNapi } from 'libentry.so'; // testNapi2 and testNapi3 should be retained.
// ...
testNapi2();
myNapi();
-keep-file-name
Retains the file/folder names. You do not need to specify the file name extension. Name wildcards are supported.
The following uses utils/file.ets as an example to describe how to configure the trustlist:
-keep-file-name
utils
file
NOTE
-
This option takes effect when
-enable-filename-obfuscationis used. -
The trustlist specified by
-keep-file-nameapplies globally. That is, the names of files or folders at different levels will not be obfuscated as long as they match the names in the trustlist configured in-keep-file-name. -
Path wildcards are not supported, for example:
# Only the path is retained. The names of files and folders in the pages directory are still obfuscated. -keep-file-name ./src/main/ets/components/pages/**
File Names Requiring Manual Trustlist Configuration
- When
requireis used to import file paths, the path should be retained. This is becauseArkTSdoes not support CommonJS syntax.
// example.js
const module1 = require('./file1'); // file1 should be retained.
- For dynamically imported paths, the paths should be retained. This is because the system cannot determine whether the parameters in the
importfunction are paths.
// file2.ts
export function foo () {}
// main.ts
const moduleName = './file2'; // The path name file2 corresponding to moduleName should be retained.
async function func2() {
const modules = await import(moduleName);
const result = modules.foo();
}
- For API version 19 and earlier versions, when cross-package dynamic routing is used for navigation, the path passed to the dynamic routing should be retained. Dynamic routing provides two modes: system routing table and custom routing table.
If a custom routing table is used for redirection, the way to configure a trustlist is consistent with the second dynamic reference scenario.
However, if the system routing table is used for redirection, the path corresponding to the pageSourceFile field in the resources/base/profile/route_map.json file of the module should be added to the trustlist.
For API version 20 and later versions, you do not need to manually configure the trustlist.
{
"routerMap": [
{
"name": "PageOne",
"pageSourceFile": "src/main/ets/pages/directory/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description" : "this is PageOne"
}
}
]
}
- For API version 19 and earlier versions, when AppStartup is used, the paths of the startup parameter configuration file and startup task file must be retained. These paths are configured in the
resources/base/profile/startup_config.jsonfile, corresponding to theconfigEntryfield andsrcEntryfield of thestartupTasksobject, respectively.
For API version 20 and later versions, you do not need to manually configure the trustlist.
The following is an example of the startup_config.json file:
{
"startupTasks": [
{
"name": "StartupTask_001",
"srcEntry": "./ets/startup/StartupTask_001.ets",
"dependencies": [
"StartupTask_002"
],
"runOnThread": "taskPool",
"waitOnMainThread": false
},
{
"name": "StartupTask_002",
"srcEntry": "./ets/startup/StartupTask_002.ets",
"runOnThread": "taskPool",
"waitOnMainThread": false
}
],
"configEntry": "./ets/startup/StartupConfig.ets"
}
The following shows how to configure a trustlist:
-keep-file-name
# The startup task file paths are ./ets/startup/StartupTask_001.ets and ./ets/startup/StartupTask_002.ets.
startup
StartupTask_001
StartupTask_002
# The startup parameter configuration file path is ./ets/startup/StartupConfig.ets.
StartupConfig
- If file name obfuscation rules are enabled when the route navigation method provided by a third-party library is used, the file path will be obfuscated, causing navigation failures. Therefore, you need to configure the route navigation paths under
-keep-file-nameto prevent them from being obfuscated.
-keep-comments
Retains the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration files generated after compilation. Name wildcards are supported. For example, to retain the JSDoc comments above the Human class in the declaration file, use the following configuration:
-keep-comments
Human
NOTE
-
This option takes effect when
-remove-commentsis used. -
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 retained using
-keep-comments. For example, when exportClass is configured in-keep-comments, if the class name is exportClass obfuscated, its JSDoc comments cannot be retained:/* * @class exportClass */ export class exportClass {}
-keep-dts
Adds names (such as variable names, class names, and property names) in the .d.ts file of the specified file path into the trustlist of -keep-global-name and -keep-property-name. Ensure that filepath is an absolute path or a directory. If the directory is specified, the names in all .d.ts files in the directory are retained.
-keep
Retains all names (such as variable names, class names, and property names) in the specified relative file path. filepath can be a file or directory. If it is a directory, the files in the directory and subdirectories are not obfuscated.
filepath supports only relative paths. ./ and ../ are relative to the directory where the obfuscation configuration file is located. Path wildcards are supported.
-keep
./src/main/ets/fileName.ts // Names in the fileName.ts file are not obfuscated.
../folder // Names in all the files under the folder directory and its subdirectories are not obfuscated.
../oh_modules/json5 // Names in all the files in the imported third-party library json5 are not obfuscated.
How to retain remote HAR packages in modules?
Method 1: Specify the exact path of the remote HAR package in the module-level oh_modules. This path is a symbolic link to the real path in the project-level oh_modules. When configuring the path in the module-level oh_modules as a trustlist, you should specify the bundle name or a directory following the bundle name to correctly link to the real directory path. Therefore, configuring only the parent directory name of the HAR package is not supported.
// Positive example:
-keep
./oh_modules/harName1 // Names in all the files under the harName1 directory and its subdirectories are not obfuscated.
./oh_modules/harName1/src // Names in all the files under the src directory and its subdirectories are not obfuscated.
./oh_modules/folder/harName2 // Names in all the files under the harName2 directory and its subdirectories are not obfuscated.
// Negative example:
-keep
./oh_modules // To retain the HAR package in the module-level oh_modules, configuring the parent directory name of the HAR package is not supported.
Method 2: Specify the exact path of the remote HAR package in the project-level oh_modules. Since the file paths in the project-level oh_modules are all real paths, any path can be configured.
-keep
../oh_modules // Names in all the files under the project-level oh_modules and its subdirectories are not obfuscated.
../oh_modules/harName3 // Names in all the files under the harName3 directory and its subdirectories are not obfuscated.
The following figure shows the directory structure of module-level oh_modules and project-level oh_modules in DevEco Studio.

NOTE
-
The exported names and properties of the files in the dependency links of the files retained with
-keep filepathwill also be retained. -
This option does not affect the capability provided by the
-enable-filename-obfuscationoption. -
When a file is retained using the -keep rule, the code within the file will not be obfuscated. However, when properties from this file are referenced in other files, the property names may still be obfuscated. In this case, you can refer to the common examples of the -keep rule for solutions.
Wildcards Supported by Retention Options
Name Wildcards
The table below lists the name wildcards supported.
| Wildcard | Description | Example |
|---|---|---|
| ? | Matches any single character. | "AB?" matches "ABC", but not "AB". |
| * | Matches any number of characters. | "*AB*" matches "AB", "aABb", "cAB", and "ABc". |
Use Example
Retain all property names that start with a.
-keep-property-name
a*
Retain all single-character property names.
-keep-property-name
?
Retain all property names.
-keep-property-name
*
Path Wildcards
The table below lists the path wildcards supported.
| Wildcard | Description | Example |
|---|---|---|
| ? | Matches any single character except the path separator (/). |
"../a?" matches "../ab", but not "../a/". |
| * | Matches any number of characters except the path separator (/). |
"../a*/c" matches "../ab/c", but not "../ab/d/s/c". |
| ** | Matches any number of characters. | "../a**/c" matches "../ab/c" and "../ab/d/s/c". |
| ! | 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". |
Use Example
Retain the c.ets file in the ../a/b/ directory (excluding subdirectories).
-keep
../a/b/*/c.ets
Retain the c.ets file in the ../a/b/ directory and its subdirectories.
-keep
../a/b/**/c.ets
Retain 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.
-keep
../a/b/
!../a/b/c.ets
Retain all the files in the ../a/ directory (excluding subdirectories).
-keep
../a/*
Retain all the files in the ../a/ directory and its subdirectories.
-keep
../a/**
Retain all the files in the module.
-keep
./**
NOTE
-
In these options, the wildcards
*,?, and!cannot be used for other meanings. Example:class A { '*'= 1 } -keep-property-name *In this example,
*indicates any number of characters, and all property names are retained (not obfuscated). It does not mean that only the*property is retained. -
In the -keep option, only the path format
/is allowed. The path format\or\\is not.
Obfuscation Rule Merging Strategies
During module compilation, the effective obfuscation rules are the merged result of the current module's obfuscation rules and the dependent modules' obfuscation rules. The specific rules are as follows:
Obfuscation rules of the current module
Content of the obfuscation configuration file specified by the arkOptions.obfuscation.ruleOptions.files field in the current module's configuration file build-profile.json5.
Obfuscation rules of dependent modules Depending on the type of dependent module, the obfuscation rules come from the following two sources:
-
Local HAR/HSP modules Content of the obfuscation configuration file specified by the
arkOptions.obfuscation.consumerFilesfield in the module's configuration filebuild-profile.json5. -
Remote HAR/HSP packages Content of the
obfuscation.txtfile in the remote HAR/HSP package.
If an HAP, HSP, or HAR is built, the final obfuscation rules are the merge of the following files:
- ruleOptions.files attribute of the current module
- consumerFiles attribute of the dependent local HSP
- consumerFiles attribute of the dependent local HAR
- obfuscation.txt files in the dependent remote HAR and remote HSP
If a HAR is built, the obfuscation.txt file in the generated remote HAR is the combination of the following files:
- Its own consumerFiles attribute
- consumerFiles attribute of the dependent local HSP
- consumerFiles attribute of the dependent local HAR
- obfuscation.txt files in the dependent remote HAR and remote HSP
When an HSP is built, the obfuscation.txt file in the generated remote HSP contains only its own consumerFiles property. When a HAP is built, no obfuscation.txt file is generated.
Obfuscation Rule Merging Logic
Obfuscation options: The OR operation is used for merging. If a switch option exists in any of the rule files being merged, it will be included in the final merged result. Retention options: When merging, for trustlist options, their content is the union of all.
-
If the current module's obfuscation configuration does not include the
-enable-lib-obfuscation-optionsoption, the merged result is the current module's obfuscation rules and the retention options in the dependent modules' obfuscation rules. -
If the current module's obfuscation configuration includes the
-enable-lib-obfuscation-optionsoption, the merged result is the current module's obfuscation rules and the dependent modules' obfuscation rules.
For versions earlier than API version 18, if the obfuscation configuration file specified by consumerFiles contains the following obfuscation options and retention options, these rules will be generated into the obfuscation.txt file of the remote HAR and HSP packages, and other obfuscation rules will not be retained.
// Obfuscation options
-enable-property-obfuscation
-enable-string-property-obfuscation
-enable-toplevel-obfuscation
-compact
-remove-log
// Retention options
-keep-property-name
-keep-global-name
In versions earlier than API version 18, the main module automatically merges the obfuscation options and retention options from the obfuscation.txt configuration files of its dependent remote HARs or HSPs. This may cause the obfuscation rules of the main module to be modified unexpectedly, thereby affecting the final obfuscation result.
For API version 18 and later versions, only the aforementioned retention options are merged and applied by the main module by default, while other obfuscation options are not. This design prevents other modules from being affected by the obfuscation configuration when they depend on remote HAR or HSP. In addition, when the remote HAR or HSP is packaged, the obfuscation rules in the obfuscation-rules.txt file of the remote HAR or HSP are used, which does not affect the actual obfuscation effect. If you want to restore the obfuscation rule merging logic before API version 18, you can configure the -enable-lib-obfuscation-options option.
Precautions for Obfuscation in HSP and HAR
-
If the obfuscation configuration file specified by
consumerFilescontains the above obfuscation options, when other modules depend on this HAR, these options will be merged with the main module's obfuscation rules, thereby affecting the main module. Therefore, you are not advised to configure obfuscation options in theconsumer-rules.txtfile. Instead, configure only retention options in the file. -
If the
-keep-dtsoption is added to the obfuscation configuration file specified byconsumerFiles, it will be converted into-keep-global-nameand-keep-property-name.
Mappings Between Obfuscation Options and Initial API Versions
| Obfuscation Option | Description | Initial API Version |
|---|---|---|
| -disable-obfuscation | Disables obfuscation. | 10 |
| -enable-property-obfuscation | Enables property name obfuscation. | 10 |
| -enable-string-property-obfuscation | Enables obfuscation for string literal property names. | 10 |
| -enable-toplevel-obfuscation | Enables top-level scope name obfuscation. | 10 |
| -enable-filename-obfuscation | Enables file or folder name obfuscation for the HAR. Enables file or folder name obfuscation for the HAP/HSP. |
10 12 |
| -enable-export-obfuscation | Enables obfuscation for imported/exported names. | 10 |
| -compact | Removes unnecessary spaces and all line feeds. | 10 |
| -remove-log | Removes the expressions involving direct calls to the console. statement in specific scenarios. | 10 |
| -print-namecache | Saves the name cache to the specified file path. | 10 |
| -apply-namecache | Reuses the specified name cache file. | 10 |
| -remove-comments | Removes all comments in the file. | 10 |
| -keep-property-name | Retains property names. | 10 |
| -keep-global-name | Retains top-level scope names. | 10 |
| -keep-file-name | Retains file or folder names in the HAR. Retains file or folder names in the HAP/HSP. |
10 12 |
| -keep-dts | Retains the names in the .d.ts file in the specified path. | 12 |
| -keep-comments | Retains the classes, functions, namespaces, enums, structs, interfaces, modules, types, and JsDoc comments above properties in the declaration file generated after compilation. | 12 |
| -keep | Retains all names in the specified path. | 12 |
| Wildcard | Allows wildcards in all the keep options of the name classes and path classes. | 12 |
| -print-kept-names | Prints unobfuscated names. | 18 |
| -extra-options strip-language-default | Reduces the default language trustlist. | 18 |
| -extra-options strip-system-api-args | Reduces the default system API trustlist. | 18 |
| -extra-options strip-not-compiled-module-name | Not retains the names of modules that are not compiled. | 22 |
| -keep-parameter-names | Retains declaration file parameters. | 18 |
| -enable-lib-obfuscation-options | Merges dependent module options. | 18 |
| -use-keep-in-source | Marks trustlists in source code by comments. | 19 |
| -keep-object-props | Retains the property name of the object literal. | 23 |
| -remove-nosideeffects-calls | Deletes a specified method call in a specific scenario. | 23 |