This is the 7th day of my participation in the August More Text Challenge

The ECMAScript module (ES module for short) is a mechanism for JavaScript code reuse

The ES module system has two parts:

  1. Import -import {func} from ‘./ mymodule.js’
  2. Export -export const func = () => {}

Import modules import dependencies using the import syntax:

// The importing module
import { concat } from './concatModule.js';

concat('a'.'b'); // => 'ab'
Copy the code

The imported module is itself a module exported using the export syntax:

// The imported module exports components
export const concat = (paramA, paramB) = > paramA + paramB;
Copy the code

The ES module approach is static: this means that the dependencies between modules are known at compile time and we cannot change the imports at run time

While static imports work in most cases, there are times when modules are loaded dynamically

With the introduction of Dynamic imports in 2020, we can dynamically load code in response to user interactions

Dynamic import of modules

When the import keyword is used as a function instead of static import syntax:

const module = await import(path);
Copy the code

It returns a Promise and starts an asynchronous task to load the module. If the module loads successfully, the Promise resolves to the contents of the module, otherwise, the Promise rejects

Path can be any expression that evaluates to a string indicating a path. A valid path expression is:

// Classic string literals
const module1 = await import('./myModule.js');

// A variable
const path = './myOtherModule.js';
const module2 = await import(path);

// Function call
const getPath = (version) = > `./myModule/versions/${version}.js`;
const moduleVersion1 = await import(getPath('v1.0'));
const moduleVersion2 = await import(getPath('v2.0'));
Copy the code

Because import(PATH) returns a Promise, it is well suited to async/await syntax. For example, loading a module in an asynchronous function:

async function loadMyModule() {
  const myModule = await import('./myModule.js');
  // ... use myModule
}

loadMyModule();
Copy the code

You can also do this:

async function loadMyModule(path) {
  const myModule = await import(path);
  // ... use myModule
}

loadMyModule('./myModule.js');
Copy the code

Imported components

Import Name Export

Here we export a concat function:

// namedConcat.js
export const concat = (paramA, paramB) = > paramA + paramB;
Copy the code

If you want to dynamically import namedconcat.js and access the named export concat, then simply deconstruct the parsed module object with the named export name:

async function loadMyModule() {
  const { concat } = await import('./namedConcat.js');
  concat('b'.'c'); // => 'bc'
}

loadMyModule();
Copy the code

Import Default export

If the imported module is the default export, we can access the default import by reading properties from the module object in default

Suppose the defaultconcat.js export function serves as the default export:

// defaultConcat.js
export default (paramA, paramB) => paramA + paramB;
Copy the code

When defaultconcate.js is dynamically imported, especially when accessing the default export, you only need to read the default property.

But there is a subtle difference. Default is a keyword in JavaScript, so it cannot be used as a variable name, so just use a destruct with an alias:

async function loadMyModule() {
  const { default: defaultImport } = await import('./defaultConcat.js');
  defaultImport('b'.'c'); // => 'bc'
}

loadMyModule();
Copy the code

Importing mixed content

If the imported module exports default and multiple named exports, then all of these components can also be easily accessed using a single deconstruction:

async function loadMyModule() {
  const { 
    default: defaultImport,
    namedExport1,
    namedExport2
  } = await import('./mixedExportModule.js');
  // ...
}


loadMyModule();
Copy the code

When to use dynamic imports

With dynamic import, we can split up the code and load the important code only when appropriate. Before JavaScript introduced dynamic imports, this pattern was unique to WebPack

React and Vue load blocks of code in response to events, such as user interactions or routing changes, by dynamically importing code splits

Dynamic import is recommended for large modules or modules that need to be imported based on certain conditions

async function execBigModule(condition) {
  if (condition) {
    const { funcA } = await import('./bigModuleA.js');
    funcA();
  } else {
    const { funcB } = await import('./bigModuleB.js');
    funcB();
  }
}

execBigModule(true);
Copy the code