Loading Native Modules Statically
I. Overview
In modern application development, especially with the advent of ES6 and beyond, the ability to modularize code has become increasingly important. This modularization not only helps in maintaining clean and organized codebases but also enhances the reusability and scalability of the code. In ES6, the import
syntax is used to load exported content from other files. This mechanism has been adapted in ArkTS to allow developers to conveniently import content exported from native modules (.so
files).
Native modules are typically written in lower-level languages like C or C++ and compiled into shared libraries (.so
files on Linux-based systems). These modules can provide high-performance functionalities that are not easily achievable with high-level languages like JavaScript or TypeScript. By enabling the import of native modules, ArkTS bridges the gap between high-level application logic and low-level performance-critical code.
II. Supported Import Methods
Direct Import
Direct import is the simplest and most straightforward method of importing content from native modules. This method involves exporting the content in the index.d.ts
file of the native module and then directly importing it in your TypeScript file.
Named Import
// index.d.ts for libentry.so
export const add: (a: number, b: number) => number;
// test.ets
import { add } from 'libentry.so';
console.log(add(2, 3)); // Output: 5
In this example, the add
function is exported from the libentry.so
native module. The index.d.ts
file provides type definitions for the exported functions, allowing TypeScript to understand the function signatures and provide type checking.
Default Import
// index.d.ts for libentry.so
export const add: (a: number, b: number) => number;
// test.ets
import add from 'libentry.so';
console.log(add.add(2, 3)); // Output: 5
Here, the add
function is imported as the default export. Note that the actual function is accessed using add.add
because the default export is an object containing the add
function.
Namespace Import
// index.d.ts for libentry.so
export const add: (a: number, b: number) => number;
// test.ets
import * as add from 'libentry.so';
console.log(add.add(2, 3)); // Output: 5
In this case, the entire module is imported as a namespace object. The add
function is accessed using add.add
.
Indirect Import
Indirect import involves exporting content from one file and then importing it from another file. This method can be useful for organizing code and creating intermediate layers of abstraction.
Export as Named Variables and Then Import
// test1.ets
import hilog from '@ohos.hilog';
export { hilog };
// test2.ets
import { hilog } from './test1';
hilog.info(0x000, 'testTag', '%{public}s', 'test');
In this example, the hilog
module is imported and re-exported in test1.ets
. It is then imported in test2.ets
and used to log information.
Export as Namespace and Then Import
// index.d.ts for libentry.so
export const add: (a: number, b: number) => number;
// test1.ets
export * from 'libentry.so';
// test2.ets
import { add } from './test1';
console.log(add(2, 3)); // Output: 5
Here, all exports from libentry.so
are re-exported in test1.ets
and then imported in test2.ets
.
Note: Using both named and namespace exports simultaneously for native modules is not supported. This can lead to conflicts and unexpected behavior.
Anti - example
// test1.ets
export * from 'libentry.so';
// test2.ets
import * as add from './test1';
// Unable to obtain the add object
In this anti-example, attempting to import the entire namespace from test1.ets
fails because the re-exported content from libentry.so
is not correctly handled.
Dynamic Import
Dynamic imports allow modules to be loaded at runtime, providing more flexibility and enabling features like lazy loading. This method involves using the import()
function, which returns a promise.
Direct Import
// index.d.ts for libentry.so
export const add: (a: number, b: number) => number;
// test.ets
import('libentry.so').then((ns: ESObject) => {
console.log(ns.add(2, 3)); // Output: 5
});
Here, the import()
function is used to dynamically load the libentry.so
module. The then
method is used to handle the promise and access the add
function.
Indirect Import
// test1.ets
import add from 'libentry.so';
export { add };
// test2.ets
import('./test1').then((ns: ESObject) => {
console.log(ns.add(2, 3)); // Output: 5
});
In this example, the add
function is re-exported in test1.ets
and then dynamically imported in test2.ets
.
Note: Namespace exports are not supported when dynamically loading and exporting files. This can lead to issues where the imported namespace is not correctly populated.
Anti - example
// test1.ets
export * from 'libentry.so';
// test2.ets
import('./test1').then((ns: ESObject) => {
// Unable to obtain the ns object
});
In this anti-example, attempting to dynamically import the entire namespace from test1.ets
fails because the re-exported content from libentry.so
is not correctly handled.
III. Best Practices and Considerations
Type Definitions
Ensure that the index.d.ts
file provides accurate type definitions for the exported functions. This helps TypeScript understand the function signatures and provides better type checking and autocompletion support.
Error Handling
When using dynamic imports, always include error handling to manage cases where the module fails to load. This can be done using the catch
method on the promise.
import('libentry.so')
.then((ns: ESObject) => {
console.log(ns.add(2, 3)); // Output: 5
})
.catch((error) => {
console.error('Failed to load module:', error);
});
Performance Considerations
Dynamic imports can improve performance by allowing lazy loading of modules. However, they can also introduce complexity and potential delays. Use them judiciously based on your application's requirements.
Testing
Thoroughly test your application to ensure that all imports and exports work as expected. Pay special attention to edge cases, such as importing from modules that may not be available at runtime.
Top comments (0)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.