iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 24
0
Modern Web

從ES到ESNext - 30天輕鬆掌握ECMAScript系列 第 24

ES2020(ES11) - ESM模組

本系列文章經過重新編排和擴充,已出書為ECMAScript關鍵30天。原始文章因當時準備時程緊迫,多少有些許錯誤。為了避免造成讀者的困擾,以及配合書籍的內容規劃,將會陸續更新本系列文章。
本篇文章在 2021/11/8 已更新。

Dynamic import

在模組化開發下,我們會以import的方式匯入需要的模組。但是因為import是屬於靜態函式,如果有些模組是在特定條件下才會用到的話,程式裡面還是會包含到這些模組,某些情況下可能只是徒增執行檔的大小。

不過有些 framework 或打包工具有針對這部分提供了解決方案。像是 React 內建的 lazysuspense API,或是第三方套件 React Loadable,讓開發者先享受到動態載入的便利性。

在 ES2020 後,import終於也可以動態載入。透過 Promise 的包裝,讓在特定條件下執行載入的模組,可以在回傳的 promise 中取得。

btn.onclick = () => {
  // promise chaining 的方式
  import("./moduleA.js")
    .then((module) => {
      // Do something with the module.
    })
    .catch((err) => {
      // load error;
    });

    // 使用await的方式
    let module = await import("./moduleA.js");
};


動態匯入 json 檔也可以。

const loadUserProfile = () => import("./user/profile.json");
loadUserProfile().then(
  (value) => value?.default && setUserProfile(value.default)
);

如果使用 Babel 轉譯的話,在外掛的列表上需要加上 @babel/plugin-syntax-dynamic-import。如果有使用 @babel/preset-env 的 preset 的話就不用額外設定。

Module Namespace Exports

當要匯入某個檔案的所有輸出函式,為了語意性和方便性,我們會為這些匯入的函式放在一個 namespace 底下。

import * as Util from "../utils";

相對地 export 並沒有支援 namespace。所以我們很常在函式庫的入口處會這樣寫 -

import * as Util from "../utils";
export { Utils };

在 ES2020 後,export 也能像 import 一樣以 namespace 輸出了。

export * as Utils from "../utils";

import.meta

針對匯入的 JS 模組檔案提供相關訊息的物件,像是模組的路徑等。

<script type="module" src="my-module.js"></script>;

console.log(import.meta); // { url: "file:///home/user/my-module.js" }

參考資源


上一篇
ES2020(ES11) - 運算子
下一篇
ES2020(ES11) - string、bigint、Promise、globalThis
系列文
從ES到ESNext - 30天輕鬆掌握ECMAScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言