• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Shared Module
2
3A shared module, marked with **use shared**, is loaded only once in a process.
4
5A non-shared module is loaded once in the same thread and multiple times in different threads, creating a new module object in each thread. Shared modules, however, can be used to implement process-wide singletons.
6
7
8## Constraints
9
10- Similar to **use strict**, **use shared** must be placed at the top level of ArkTS files and should appear after **import** statements but before any other code.
11
12  The shared property cannot be passed on. That is, importing a shared module does not make a non-shared module shared.
13
14
15- Shared modules are only supported in .ets files.
16
17- **side-effects-import** is not allowed in shared modules.
18
19  A shared module is loaded only once within a single process and can be used across multiple threads.
20
21  When a shared module is loaded, non-shared modules that it imports are not loaded immediately. Instead, these non-shared modules are lazy-imported within the current thread when their exported variables are accessed. This lazy loading ensures that non-shared modules remain isolated between threads, with each thread potentially loading the module once if needed.
22
23  side-effects-import, which does not involve exported variables, is never loaded and therefore is not supported.
24
25  ```ts
26  // side-effects-import is not allowed.
27  import "./sharedModule"
28  ```
29
30- All variables exported by shared modules must be Sendable objects.
31
32  Since shared modules are shared across concurrent instances, all exported objects must be Sendable. For details, see [Usage Rules and Constraints for Sendable](sendable-constraints.md).
33
34- Modules cannot be directly exported from a shared module.
35
36  ```ts
37  // test.ets
38  export let num = 1;
39  export let str = 'aaa';
40
41  // Shared module
42  'use shared'
43
44  export * from './test'; // A compile-time error is reported. The module cannot be directly exported.
45  export {num, str} from './test'; // Correct example. Export the object set.
46  ```
47
48
49- Shared modules can import or be imported by both shared and non-shared modules. There are no restrictions on importing or being imported by shared modules.
50
51- **napi_load_module** and **napi_load_module_with_info** support loading of shared modules.
52
53- Dynamic loading does not support loading of shared modules.
54
55## Usage Example
56
571. Export a Sendable object from a shared module.
58
59   ```ts
60   // Shared module sharedModule.ets
61   import { ArkTSUtils } from '@kit.ArkTS';
62
63   // Declare the current module as shared. Only Sendable data can be exported.
64   "use shared"
65
66   // Shared module. SingletonA is globally unique.
67   @Sendable
68   class SingletonA {
69     private count_: number = 0;
70     lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock()
71
72     public async getCount(): Promise<number> {
73       return this.lock_.lockAsync(() => {
74         return this.count_;
75       })
76     }
77
78     public async increaseCount() {
79       await this.lock_.lockAsync(() => {
80         this.count_++;
81       })
82     }
83   }
84
85   export let singletonA = new SingletonA();
86   ```
87
882. Operate an object exported from the shared module across multiple threads.
89
90   ```ts
91   import { taskpool } from '@kit.ArkTS';
92   import { singletonA } from './sharedModule';
93
94   @Concurrent
95   async function increaseCount() {
96     await singletonA.increaseCount();
97     console.info("SharedModule: count is:" + await singletonA.getCount());
98   }
99
100   @Concurrent
101   async function printCount() {
102     console.info("SharedModule: count is:" + await singletonA.getCount());
103   }
104
105   @Entry
106   @Component
107   struct Index {
108     @State message: string = 'Hello World';
109
110     build() {
111       Row() {
112         Column() {
113           Button("MainThread print count")
114             .onClick(async () => {
115               await printCount();
116             })
117           Button("Taskpool print count")
118             .onClick(async () => {
119               await taskpool.execute(printCount);
120             })
121           Button("MainThread increase count")
122             .onClick(async () => {
123               await increaseCount();
124             })
125           Button("Taskpool increase count")
126             .onClick(async () => {
127               await taskpool.execute(increaseCount);
128             })
129         }
130         .width('100%')
131       }
132       .height('100%')
133     }
134   }
135   ```
136