<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jeop-f</title>
    <description>The latest articles on DEV Community by Jeop-f (@jeopf).</description>
    <link>https://dev.to/jeopf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3298771%2Fbd1b503e-d90c-422a-9af6-f21fe010d2fb.png</url>
      <title>DEV Community: Jeop-f</title>
      <link>https://dev.to/jeopf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jeopf"/>
    <language>en</language>
    <item>
      <title>ArkTSvsTypeScript:lazy-import</title>
      <dc:creator>Jeop-f</dc:creator>
      <pubDate>Mon, 30 Jun 2025 02:21:33 +0000</pubDate>
      <link>https://dev.to/jeopf/arktsvstypescriptlazy-import-153a</link>
      <guid>https://dev.to/jeopf/arktsvstypescriptlazy-import-153a</guid>
      <description>&lt;p&gt;As the functionality of applications continues to expand, the time required for cold start has significantly increased, primarily due to the loading of a large number of modules during the initial startup phase, many of which contain redundant files that are not actually executed. This situation not only delays the application's initialization process but also results in ineffective resource occupation. It is imperative to take measures to streamline the loading process, eliminate the execution of unnecessary files, optimize cold start performance, and ensure the smoothness of the user experience.&lt;/p&gt;

&lt;p&gt;Note&lt;/p&gt;

&lt;p&gt;Lazy loading functionality is supported starting from API version 12.&lt;br&gt;
Developers must configure "compatibleSdkVersionStage": "beta3" in the project to use the lazy import syntax on API 12; otherwise, the compilation will fail.&lt;/p&gt;

&lt;p&gt;Features&lt;br&gt;
The lazy loading feature allows pending files to not be loaded during the cold start phase. Instead, these files are only loaded when the application actually needs them during runtime, thus reducing the time required for the cold start.&lt;/p&gt;

&lt;p&gt;Usage&lt;br&gt;
Developers can use tools like Trace or logging to identify files that were not actually called during the cold start. By analyzing this data, developers can accurately determine a list of files that do not need to be preloaded during the startup phase. For the call points of these files, the lazy attribute can be directly added. However, it should be noted that subsequent loading is done synchronously, which may block task execution (for example, if a click task triggers lazy loading, the runtime will execute the files not loaded during cold start, thereby increasing the time required).&lt;br&gt;
 Therefore, whether to use lazy loading needs to be assessed by the developer themselves.&lt;/p&gt;

&lt;p&gt;Describe&lt;br&gt;
Developers are not recommended to blindly increase the use of lazy, as it may increase the recognition overhead during both compilation and runtime.&lt;/p&gt;

&lt;p&gt;Scene Behavior Analysis&lt;br&gt;
Use lazy-import for deferred loading.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.ets
import lazy { a } from "./mod1";    // "mod1" Not executed
import { c } from "./mod2";         // "mod2" execute

// ...

console.info("main executed");
while (false) {
    let xx = a;
}

// mod1.ets
export let a = "mod1 executed"
console.info(a);

// mod2.ets
export let c = "mod2 executed"
console.info(c);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result is as follows:&lt;br&gt;
    mod2 executed&lt;br&gt;
    main executed&lt;br&gt;
Reference both lazy-import and native import for the same module.&lt;br&gt;
    // main.ets&lt;br&gt;
    import lazy { a } from "./mod1";    // "mod1" Not executed&lt;br&gt;
    import { c } from "./mod2";         // "mod2" executed&lt;br&gt;
    import { b } from "./mod1";         // "mod1" executed&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ...

console.info("main executed");
while (false) {
    let xx = a;
}

// mod1.ets
export let a = "mod1 a executed"
console.info(a);

export let b = "mod1 b executed"
console.info(b);

// mod2.ets
export let c = "mod2 c executed"
console.info(c);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The result is as follows:&lt;br&gt;
    mod2 c executed&lt;br&gt;
    mod1 a executed&lt;br&gt;
    mod1 b executed&lt;br&gt;
    main executed&lt;/p&gt;

&lt;p&gt;If the lazy keyword is deleted in main.ets, the order of execution is as follows:&lt;br&gt;
    mod1 a executed&lt;br&gt;
    mod1 b executed&lt;br&gt;
    mod2 c executed&lt;br&gt;
    main executed&lt;br&gt;
Syntax specifications&lt;br&gt;
lazy-import supports the following commands:&lt;/p&gt;

&lt;p&gt;grammar ModuleRequest   ImportName  LocalName   Whether API12 supports lazy loading&lt;br&gt;
import lazy { x } from “mod”;   “mod”   “x” “x” support&lt;br&gt;
import lazy { x as v } from “mod”;  “mod”   “x” “v” support&lt;/p&gt;

&lt;p&gt;Lazy loading of shared modules or the inclusion of shared modules within a dependency path.&lt;br&gt;
Lazy loading is still valid for shared modules, see the Shared Module Development Guide for usage restrictions.&lt;/p&gt;

&lt;p&gt;Examples of errors&lt;br&gt;
The following will cause a compilation error.&lt;br&gt;
    export lazy var v;                  //Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy default function f(){}; // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy default function(){};   // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy default 42;             // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy { x };                    // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy { x as v };               // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy { x } from "mod";         // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy { x as v } from "mod";    // Compiler Error Message: An application compilation error is reported&lt;br&gt;
    export lazy * from "mod";           // Compiler Error Message: An application compilation error is reported&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import lazy v from "mod";           // Compiler Error Message: An application compilation error is reported
import lazy * as ns from "mod";     // Compiler Error Message: An application compilation error is reported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Using the type keyword together with the keyword will result in an error.&lt;br&gt;
    import lazy type { obj } from "./mod";    // No, the compiler and application compilation error is reported&lt;br&gt;
    import type lazy { obj } from "./mod";    // No, the compiler and application compilation error is reported&lt;/p&gt;

&lt;p&gt;Not recommended&lt;br&gt;
In the same ets file, the dependent module markup that expects lazy loading is incomplete.&lt;br&gt;
Incomplete tagging will result in lazy loading invalidation and increase the overhead of identifying lazy loads.&lt;br&gt;
    // main.ets&lt;br&gt;
    import lazy { a } from "./mod1";    // Get the A object from inside "mod1" and mark it as lazy loaded&lt;br&gt;
    import { c } from "./mod2";&lt;br&gt;
    import { b } from "./mod1";         // Get the attributes in "mod1" again, "mod1" is not marked lazy, and "mod1" is executed by default&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In the same ETS file, lazy loading variables are not used and exported again, lazy loading variables are not supported to be re-exported.&lt;br&gt;
The variable c exported in this way is not used in B.ets, and the file B.ets does not trigger execution. When variable a is used in file A.ets, the variable is not initialized and a js exception is thrown.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// A.ets
import { c } from "./B";
console.info(c);

// B.ets
import lazy { c } from "./C";    // Get the A object from inside "mod1" and mark it as lazy loaded
export { c }

// C.ets
function c(){};
export { c }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Result:&lt;br&gt;
    ReferenceError: a is not initaliized&lt;br&gt;
         at func_main_0 (A.ets:2:1)&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// A_ns.ets
import * as ns from "./B";
console.info(ns.c);

// B.ets
import lazy { c } from "./C";    // Get the A object from inside "mod1" and mark it as lazy loaded
export { c }

// C.ets
function c(){};
export { c }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;ReferenceError: module environment is undefined&lt;br&gt;
    at func_main_0 (A_ns.js:2:1)&lt;br&gt;
Lazy-import lazy loading kit is not supported.&lt;br&gt;
Developers need to assess the impact of using lazy loading.&lt;br&gt;
Side-effects that do not depend on the execution of the module (such as initializing global variables, mounting globalThis, etc.).&lt;br&gt;
When using export objects, the time taken to trigger lazy loading leads to the deterioration of the functionality of the corresponding feature.&lt;br&gt;
A bug caused by the use of the lazy feature causing the module to not be executed.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ArkTSvsTypeScript:KeyDifferencesforHarmonyOS Devs</title>
      <dc:creator>Jeop-f</dc:creator>
      <pubDate>Fri, 27 Jun 2025 06:13:50 +0000</pubDate>
      <link>https://dev.to/jeopf/arktsvstypescriptkeydifferencesforharmonyosdevs-318m</link>
      <guid>https://dev.to/jeopf/arktsvstypescriptkeydifferencesforharmonyosdevs-318m</guid>
      <description>&lt;p&gt;AssetUtil is a security storage utility based on HarmonyOS AssetStoreKit, designed for securely storing, retrieving, and managing sensitive data (such as keys, credentials, etc.). It provides simple APIs for operating encrypted assets with support for both synchronous and asynchronous modes. Features ✅ Secure Storage: Protects sensitive data using system-level encryption&lt;/p&gt;

&lt;p&gt;⚡ Sync/Async Operations: Supports both synchronous and asynchronous methods&lt;/p&gt;

&lt;p&gt;🔍 Device Compatibility Check: Automatically detects device support&lt;/p&gt;

&lt;p&gt;🛡️ Conflict Handling: Built-in overwrite conflict resolution&lt;/p&gt;

&lt;p&gt;📦 Persistence Support: Optional persistent storage (enabled by default)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { asset } from '@kit.AssetStoreKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { LogUtil } from 'zcommon';
import { util } from '@kit.ArkTS';


function stringToArray(str: string): Uint8Array {
  let textEncoder = new util.TextEncoder();
  return textEncoder.encodeInto(str);
}

function arrayToString(arr: Uint8Array): string {
  let textDecoder = util.TextDecoder.create("utf-8", { ignoreBOM: true });
  let str = textDecoder.decodeToString(arr, { stream: false })
  return str;
}


export class AssetUtil {

  static canIUse(): boolean {
    return canIUse('SystemCapability.Security.Asset');
  }

  private static createAssetMap(key: string, value: string, e10: boolean = true): asset.AssetMap {
    const attr = new Map&amp;lt;asset.Tag, Uint8Array | asset.SyncType | asset.ConflictResolution | boolean&amp;gt;();
    attr.set(asset.Tag.ALIAS, stringToArray(key));
    attr.set(asset.Tag.SECRET, stringToArray(value));
    attr.set(asset.Tag.SYNC_TYPE, asset.SyncType.THIS_DEVICE);
    attr.set(asset.Tag.CONFLICT_RESOLUTION, asset.ConflictResolution.OVERWRITE); // Overwrite existing assets in case of conflict
    /*
     *The meta-service does not support this API.
     */

    /*if (e10) {
      attr.set(asset.Tag.IS_PERSISTENT, e10); // Whether to keep assets when uninstalling the app
    }*/
    return attr;
  }


  private static createQuery(key: string, isRemove: boolean = false): asset.AssetMap {
    const query = new Map&amp;lt;asset.Tag, Uint8Array | asset.ReturnType&amp;gt;();
    query.set(asset.Tag.ALIAS, stringToArray(key));
    if (!isRemove) {
      query.set(asset.Tag.RETURN_TYPE, asset.ReturnType.ALL);
    }
    return query;
  }


  private static extractSecret(result: asset.AssetMap[]): string {
    if (!result || result.length &amp;lt; 1) {
      return '';
    }
    const map = result[0];
    const secret = map.get(asset.Tag.SECRET) as Uint8Array;
    return secret ? arrayToString(secret) : '';
  }

  static async add(key: string, value: string, e10: boolean = true): Promise&amp;lt;boolean&amp;gt; {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module');
        return false;
      }
      const attr = AssetUtil.createAssetMap(key, value, e10);
      await asset.add(attr);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-add-error~ code: ${error.code} -·- message: ${error.message}`);
      return false;
    }
  }


  static addSync(key: string, value: string, e10: boolean = true): boolean {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module');
        return false;
      }
      const attr = AssetUtil.createAssetMap(key, value, e10);
      asset.addSync(attr);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-addSync-error ~ code: ${error.code} -·- message: ${error.message}`);
      return false;
    }
  }


  static async get(key: string): Promise&amp;lt;string&amp;gt; {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module');
        return '';
      }
      const query = AssetUtil.createQuery(key);
      const result = await asset.query(query);
      return AssetUtil.extractSecret(result);
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-get-error~ code: ${error.code} -·- message: ${error.message}`);
      return '';
    }
  }

  static getSync(key: string): string {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module.');
        return '';
      }
      const query = AssetUtil.createQuery(key);
      const result = asset.querySync(query);
      return AssetUtil.extractSecret(result);
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-getSync-error ~ code: ${error.code} -·- message: ${error.message}`);
      return '';
    }
  }

  static async remove(key: string): Promise&amp;lt;boolean&amp;gt; {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module.');
        return false;
      }
      const query = AssetUtil.createQuery(key, true);
      await asset.remove(query);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-remove-error~ code: ${error.code} -·- message: ${error.message}`);
      return false;
    }
  }



  static removeSync(key: string): boolean {
    try {
      if (!AssetUtil.canIUse()) {
        LogUtil.e('AssetStore-The current device does not support this module.');
        return false;
      }
      const query = AssetUtil.createQuery(key, true);
      asset.removeSync(query);
      return true;
    } catch (err) {
      const error = err as BusinessError;
      LogUtil.e(`AssetStore-removeSync-error~ code: ${error.code} -·- message: ${error.message}`);
      return false;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>artts</category>
      <category>harmonyos</category>
    </item>
  </channel>
</rss>
