DEV Community

Cover image for Module loading side effects and optimization
liu yang
liu yang

Posted on

Module loading side effects and optimization

Module Loading and Execution in ArkTS Modules

I. Overview

When using ArkTS moduleization, module loading and execution can cause side - effects. These are unintended behaviors or state changes beyond exporting functions or objects, which may lead to unexpected top - level code execution, global state changes, prototype chain modifications, or undefined imported content.

II. Side - Effect Scenarios and Optimization in ArkTS Moduleization

1. Module Top - Level Code Execution

  • Side - Effect Scenario: When a module is imported, all top - level code in the module file runs immediately, not just the exported parts. This can cause unintended behavior.
  • Example:

    // module.ets
    console.log("Module loaded!"); // This code runs immediately on import.
    export const data = 1;
    
    // main.ets
    import { data } from './module';
    console.log(data);
    
  • Output:

    Module loaded!
    1
    
  • Optimization Method 1: Remove top - level code and export only necessary content.

    // module.ets
    export const data = 1;
    
    // main.ets
    import { data } from './module';
    console.log(data);
    
  • Optimization Method 2: Encapsulate side - effect - prone code in functions or methods.

    // module.ets
    export function initialize() {
        console.log("Module loaded!");
    }
    export const data = 1;
    
    // main.ets
    import { data } from './module';
    console.log(data);
    

2. Modifying Global Objects

  • Side - Effect Scenario: Top - level code or imported modules may alter global variables, changing global state and causing side - effects.
  • Example:

    // module.ets
    export let data1 = "data from module";
    globalThis.someGlobalVar = 100;
    
    // sideEffectModule.ets
    export let data2 = "data from side effect module";
    globalThis.someGlobalVar = 200;
    
    // moduleUseGlobalVar.ets
    import { data1 } from './module';
    export function useGlobalVar() {
        console.log(data1);
        console.log(globalThis.someGlobalVar);
    }
    
    // main.ets
    import { data1 } from "./module";
    import { data2 } from "./sideEffectModule";
    import { useGlobalVar } from './moduleUseGlobalVar';
    
    useGlobalVar();
    function maybeNotCalledAtAll() {
        console.log(data1);
        console.log(data2);
    }
    
  • Output:

    data from module
    200
    
  • Optimization: Encapsulate side - effect - prone code in functions or methods.

    // module.ets
    export let data1 = "data from module";
    export function changeGlobalVar() {
        globalThis.someGlobalVar = 100;
    }
    
    // sideEffectModule.ets
    export let data2 = "data from side effect module";
    export function changeGlobalVar() {
        globalThis.someGlobalVar = 200;
    }
    
    // moduleUseGlobalVar.ets
    import { data1, changeGlobalVar } from './module';
    export function useGlobalVar() {
        console.log(data1);
        changeGlobalVar();
        console.log(globalThis.someGlobalVar);
    }
    
    // main.ets
    import { data1 } from "./module";
    import { data2 } from "./sideEffectModule";
    import { useGlobalVar } from './moduleUseGlobalVar';
    
    useGlobalVar();
    function maybeNotCalledAtAll() {
        console.log(data1);
        console.log(data2);
    }
    
  • Output:

    data from module
    100
    

3. Modifying Application - Level ArkUI Component State Variables

  • Side - Effect Scenario: A child component's state variable is modified, causing the parent component to fail to detect changes and update.
  • Example:

    // ParentComponent.ets
    @State() childState: number = 0;
    
    build() {
        Column() {
            Button("Update State").onClick(() => {
                this.childState++;
            });
            ChildComponent(this.childState);
        };
    }
    
    // ChildComponent.ets
    export function ChildComponent(state: number) {
        console.log(state); // Logs the initial state value.
        return Column() {
            Text("Child Component: " + state);
        };
    }
    
  • Output: Child component's state is not automatically updated.

  • Optimization: Use a state management solution like a reactive system or context API to ensure the parent component detects state changes and updates correctly.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.