Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Get a complete understanding of the ECMAScript module


May 31, 2021 Article blog


Table of contents


About the ES module, this article will provide some detailed interpretation, I hope to help you!

What is an ES module?

The ECMAScript module (ES module) is a mechanism for code reuse in JavaScript, introduced in 2015. In a highly fragmented JavaScript module scenario, it finally became the standard.

Until 2015, JavaScript did not have a standard code reuse mechanism. There have been many attempts at standardization in this area, leading to the fragmentation of these years.

You've probably heard of AMD modules, UMDs, or CommonJS. T here are no obvious winners. Finally, with ECMAScript 2015, the ES module lands in the language.

We now have an "official" modular system.

ECMAScript modules everywhere?

In theory, ECMAScript modules should be common to all JavaScript environments. In fact, the browser is still the primary target of the ES module.

In May 2020, node .js v12.17.0 when shipped, the ECMAScript module was supported without a logo. This means that we can now use imports and exports in Node .js without any additional command line flags.

There is still a long way to go before the ECMAScript module can work universally in any JavaScript environment, but in the right direction.

What is the ES module like?

An ES module is a simple file that we can declare one or more exits. Take this fictional utils .js.

// utils.js
export function funcA() {
  return "Hello named export!";
}


export default function funcB() {
  return "Hello default export!";
}

We have two exports here.

The first is a named export, followed by a default export, which is represented as the export default.

Assuming that our project folder is home to a file called utils .js, we can import the objects provided by this module in another file.

How to import from an ES module

Let's say we also have a file called consumer .js in the project folder. To import the functions exposed by utils .js, we can do so.

// consumer.js
import { funcA } from "./util.js";

This syntax is a named import method that is similar to the named export method.

If we want to import funcB defined as a default export, we can do this:

// consumer.js
import funcB from "./util.js";

If we want to import both the default and named exports in a file, we can compress it into:

// consumer.js
import funcB, { funcA } from "./util.js";


funcB();
funcA();

We can also import the entire module with star.

import * as myModule from "./util.js";


myModule.funcA();
myModule.default();

Note that in this case, the default export must be explicitly called.

To import from a remote module.

import { createStore } from "https://unpkg.com/[email protected]/es/redux.mjs";


const store = createStore(/* do stuff */)

The ECMAScript module in the browser

Modern browsers support ES modules, although there are some considerations. To load a module, add the module to the type property of the script label.








    
    ECMAScript modules in the browser




<p id="el">The result is: </p>




    import { appendResult } from "./myModule.js";


    const el = document.getElementById("el");
    appendResult(el);



Here myModule .js is a simple module under the same project folder.

export function appendResult(element) {
  const result = Math.random();
  element.innerText += result;
}

Although the ES module can be used directly in browsers, the task of bundling JavaScript applications is now exclusive to tools such as webpack for maximum flexibility, code splitting, and compatibility with older browsers.

Dynamic import

The ES module is static, which means that we cannot change the import at runtime. With dynamic import for 2020 logins, we can dynamically load our code based on user interaction (webpack was available before the dynamic import feature was available in ECMAScript 2020).

Consider a simple HTML that can load a script.








    
    Dynamic imports




<button id="btn">Load!</button>





You can also consider using several exported JavaScript modules.

// util.js
export function funcA() {
  console.log("Hello named export!");
}


export default function funcB() {
  console.log("Hello default export!");
}

If you want to load this module dynamically, maybe with a click, we can do so.

// loader.js
const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  // loads named export
  import("./util.js").then(({ funcA }) => {
    funcA();
  });
});

Here, we load only named exports by refactoring the module's objects.

({ funcA }) => {}

ES modules are actually JavaScript objects: we can refactor their properties, or we can call any of their exposed methods.

To dynamically import a default export, we can do so.

// loader.js
const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  // loads entire module
  // runs default export
  import("./util.js").then((module) => {
    module.default();
  });
});

When we import a module as a whole, we can use all of its output.

// loader.js
const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  // loads entire module
  // uses everything
  import("./util.js").then((module) => {
    module.funcA();
    module.default();
  });
});

There is also a common way to import dynamically, and we extract logic at the top of the file.

const loadUtil = () => import("./util.js");


const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  //
});

Here, loadUtil returns a Promise, ready for chaining.

const loadUtil = () => import("./util.js");


const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  loadUtil().then(module => {
    module.funcA();
    module.default();
  });
});

Dynamic imports look good, but what's the use of them?

With dynamic import, we can split our code and load important content only at the right time. This mode was unique to webpack, a module bundle, before dynamically importing into JavaScript.

Front-end libraries such as React and Vue use a lot of code split through dynamic imports to load chunk code in response to events, such as user interaction or routing changes.

Dynamic import of JSON files

Suppose you have a JSON file, person.json, somewhere in the code base.

{
  "name": "Jules",
  "age": 43
}

Now, you want to import this file dynamically in response to the interaction of some users.

Because the JSON file export is only a default export, it is not a function, so you can only access the default export like this.

const loadPerson = () => import("./person.json");


const btn = document.getElementById("btn");


btn.addEventListener("click", () => {
  loadPerson().then(module => {
    const { name, age } = module.default;
    console.log(name, age);
  });
});

Here, we refactor name andage from the default export.

    const { name, age } = module.default;

Use async/await for dynamic import

The import() statement always returns a Promise, which means that we can use async/await on it.

const loadUtil = () => import("./util.js");


const btn = document.getElementById("btn");


btn.addEventListener("click", async () => {
  const utilsModule = await loadUtil();
  utilsModule.funcA();
  utilsModule.default();
});

Dynamic import name

When importing a module with import(), you can name it as you like, as long as it's consistent.

  import("./util.js").then((module) => {
    module.funcA();
    module.default();
  });

or:

  import("./util.js").then((utilModule) => {
    utilModule.funcA();
    utilModule.default();
  });

The article comes from the public number: front-end development blog

The above is W3Cschool编程狮 about a comprehensive understanding of the ECMAScript module related to the introduction, I hope to help you.