1# ArkTS Modular Loading 2 3 4## Error Messages Related to Modular Loading Displayed at the Runtime of ArkTS Applications 5### "Cannot find dynamic-import module 'xxxx'" 6 7This error indicates that the module to load is not compiled into the application package. 8 9**Possible cause** 10 11An expression is dynamically loaded as an input parameter, but the module path is incorrect. 12``` typescript 13 import(module).then(m=>{m.foo();}).catch((e: Error)=>{console.info(e.message)}); 14``` 15 16**Locating method** 17 18Print the path information of the module, and check whether the path is correct. 19 20### "Cannot find module 'xxxx' , which is application Entry Point" 21This error indicates that the entry file is not found during application startup. 22 23**Possible cause** 24 25The entry file is not found during application startup. 26 27**Locating method** 28 29(1) Open the application's project-level build file **module.json5** in the **entry/src/main** directory. 30 31 32The following is an example of some parameters in **module.json5**. 33``` 34{ 35 "module": { 36 "name": "entry", 37 "type": "entry", 38 ... 39 "abilities": [ 40 { 41 "name": "EntryAbility", // Module name. 42 "srcEntry": "./ets/entryability/EntryAbility.ts", // Relative path of the src directory to the project root directory. 43 "description": "$string:EntryAbility_desc", 44 "icon": "$media:icon", 45 "label": "$string:EntryAbility_label", 46 "startWindowIcon": "$media:icon", 47 "startWindowBackground": "$color:start_window_background", 48 "exported": true, 49 "skills": [ 50 { 51 "entities": [ 52 "entity.system.home" 53 ], 54 "actions": [ 55 "action.system.home" 56 ] 57 } 58 ] 59 } 60 ] 61 } 62} 63``` 64(2) Check the value of **srcEntry** under **abilities** in **module.json5**. This parameter specifies the path of the entry file. 65 66### "No export named 'xxxx' which exported by 'xxxx'" 67This error indicates that no specific object is found in the module when the .so file in the HAP or HAR of the application is being loaded. 68 69**Possible cause** 70 71The dependency between modules is pre-parsed in the static build phase of the module. If the imported variable name in the .ets file is incorrect, an error message is displayed in DevEco Studio. An error message is also displayed in the application build phase. Note that the dependency of native C++ modules in the application is checked only at runtime. 72 73**Locating method** 74 75Check whether the .so file in the application contains the exported variable that causes the error, and compare the exported variable with the imported variable in the .so file. If they are inconsistent, modify the variable. 76 77 78## Failure in Loading .so Files 79 80If a .so file fails to be loaded, a JS error indicating loading failure is not explicitly thrown. You can check whether the exported object is **undefined** to determine the loading status of the .so file. 81 82**Loading failure symptom** 83 84| Loading Type| TS/JS Module| System Library/Application .so File| 85| -------- | -------- | -------- | 86| Static loading| The VM automatically throws an error and the process exits.| No error is thrown, and the loaded object is **undefined**.| 87| Dynamic loading| No error is proactively thrown and the program reaches the reject branch. You can call the **catch** method to capture the error.| No error is proactively thrown and the program reaches the resolve branch. You can check whether the variable exported by the module is **undefined** in the branch.| 88 89**Example 1: Static loading of the system library/application .so file fails.** 90 91``` 92import testNapi from 'libentry.so' 93 94if (testNapi == undefined) { 95 console.error('load libentry.so failed.'); 96} 97``` 98 99Command output: 100``` 101load libentry.so failed. 102``` 103 104**Example 2: Dynamic loading of the system library/application .so file fails.** 105 106``` 107import('libentry.so') 108 .then(m => { 109 if (typeof m.default === 'undefined') { 110 console.warn(`load libentry.so failed.`); 111 } else { 112 console.info('load libentry.so success:', m); 113 } 114 return m; 115 }) 116 .catch((e: Error) => { 117 console.error('load libentry.so error:', e); 118 }); 119``` 120 121Command output: 122``` 123load libentry.so failed. 124``` 125 126**Possible cause, locating method, and solution** 127 128For details, see [Node-API FAQs](https://gitee.com/openharmony/docs/blob/master/en/application-dev/napi/use-napi-faqs.md). 129 130 131## Initialization Errors at Runtime Caused by Inter-Module Circular Dependency 132### Locating Circular Dependencies 133The error message "xxx is not initialized" may not be caused by circular dependencies. You need to enable the switch for further confirmation. 134``` 135Enable the switch by running option: hdc shell param set persist.ark.properties 0x2000105c. 136After the switch is enabled, run the hdc shell reboot command to restart the device. 137Disable the switch by running option: hdc shell param set persist.ark.properties 0x0000105c. 138After the switch is disabled, run the hdc shell reboot command to restart the device. 139``` 140Once the switch is enabled, the error that appears is treated as the initial error occurrence. Rectify the error. If the error message "xxx is not initialized" is still displayed, the error is caused by circular dependencies. 141 142### Circular Dependency Principle 1431. Module loading sequence 144 145 According to the ECMAScript specification, the module execution sequence is the sequence of deep traversal loading. 146 147 If the application has a loading link A -> B -> C, then the ArkTS module executes file C, file B, and file A in sequence. 148 1492. Circular dependency 150 151 In an application with a loading sequence of A -> B -> A, following the execution sequence of deep traversal, file A's status is initially set to loading. The process then moves to load file B and sets its status to loading before returning to file A. Given that file A is already marked as in the loading phase, as per the defined protocol, the system will bypass modules that are already loading, resulting in file B being executed prior to file A. 152 153 Why do some circular dependencies have no impact but some cause applications to crash? 154 155 As mentioned earlier, even though file B depends on variables from file A, file B runs before file A. If the variables from file A that are imported into file B are not used in the global scope or as static class members, file B will execute normally. However, if file B accesses the variables from file A globally or through the instantiation of classes or other similar methods, which leads to the use of these variables during its execution, the error message "xxx is not initialized" is displayed. This occurs because the circular dependency results in the variables not being initialized in time. 156 157Example: 158``` typescript 159// A.ets 160import { Animal } from './B' 161export let a = "this is A"; 162export function A() { 163 return new Animal; 164} 165 166// --------------------- 167 168// B.ets 169import { a } from './A' 170export class Animal { 171 static { 172 console.log("this is in class"); 173 let str = a; // Error: a is not initialized 174 } 175} 176``` 177**Recommended** 178 179``` typescript 180// B.ets 181import { a } from './A' 182export class Animal { 183 static { 184 console.log("this is in class"); 185 } 186 str = a; // Modification point 187} 188``` 189 190### Solution to Circular Dependencies 191[@security/no-cycle](https://developer.huawei.com/consumer/en/doc/harmonyos-guides-V5/ide_no-cycle-V5) 192 193 194## Example Error Scenarios Because ArkTS Symbols Are Not Initialized 195 196The ArkTS coding specification is a subset of the ECMAScript specification. When a symbol that has not been initialized is accessed, an error is thrown during runtime. The following common error scenarios are provided to help you locate and rectify source code errors: 197 198### Access Before const/let Declaration 199 200``` typescript 201console.log(a); // Error: Variable 'a' is used before being assigned. 202console.log(b); // Error: Variable 'b' is used before being assigned. 203 204let a = '1'; 205const b = '2'; 206``` 207**Recommended** 208 209``` 210let a = '1'; 211const b = '2'; 212 213console.log(a); 214console.log(b); 215``` 216 217 218### Instantiation Before Class Declaration 219 220``` typescript 221let a = new A(); // Error: Class 'A' used before its declaration. 222 223class A {} 224``` 225 226**Recommended** 227 228``` 229class A {} 230 231let a = new A(); 232``` 233 234### Accessing Static Properties of a Class Before Declaration 235 236``` typescript 237let a = A.a; // Error: Class 'A' used before its declaration. 238 239class A { 240 static a = 1; 241} 242``` 243 244**Recommended** 245 246``` 247class A { 248 static a = 1; 249} 250 251let a = A.a; 252``` 253 254### Accessing let and const That Are Not Declared in a Function 255 256``` typescript 257foo(); // Error: Error message:a is not initialized 258 259let a = 1; 260const b = 2; 261 262function foo() { 263 let v = a + b; 264} 265``` 266 267**Recommended** 268 269``` 270let a = 1; 271const b = 2; 272 273function foo() { 274 let v = a + b; 275} 276 277foo(); 278``` 279 280### Accessing Static Properties of a Class That Is Not Declared in a Function 281 282``` typescript 283foo(); // Error: Error message:A is not initialized 284 285class A { 286 static a = 1; 287} 288 289function foo() { 290 let v = A.a; 291 let w = new A(); 292} 293``` 294 295**Recommended** 296 297``` 298class A { 299 static a = 1; 300} 301 302function foo() { 303 let v = A.a; 304 let w = new A(); 305} 306 307foo(); 308``` 309 310### Inter-Module Circular Dependency - const/let 311 312``` typescript 313// module1.ets 314import { a, b } from './module2' 315 316export let i = 1; 317export let m = a; 318export const j = 2; 319export const n = b; 320 321// --------------------- 322 323// module2.ets 324import { i, j } from './module1' 325 326export let a = i; // Error: Error message:i is not initialized 327export const b = j; // Error: Error message:j is not initialized 328``` 329 330**Solution** 331 332For details, see [Solution to Circular Dependencies](#solution-to-circular-dependencies). 333 334 335### Inter-Module Circular Dependency - Class 336 337``` typescript 338// class1.ets 339import { b } from './class2' 340 341export class A { 342 static a = b; 343} 344 345// --------------------- 346 347// class2.ets 348import { A } from './class1' 349export let b = 1; 350 351const i = A.a; // Error: Error message:A is not initialized 352const j = new A(); // Error: Error message:A is not initialized 353``` 354 355**Solution** 356 357For details, see [Solution to Circular Dependencies](#solution-to-circular-dependencies). 358