> For the complete documentation index, see [llms.txt](https://strctr.gitbook.io/programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://strctr.gitbook.io/programming/01-languages/javascript/01-language/d-modules/06-dynamic-import.md).

# 06. Dynamic Import

By default ES modules completely static:

* all imports should be resolved at compile time;
* import declaration can only appear at the top level of a module;
* module specifier in import expression if fixed and can not contain variables and expressions.

Dynamic import proposal adds to JS a **dynamic import operator**:

* The parameter is a string with a module specifier.
* Can be any expression whose result can be coerced to a string.
* The result of the import operator is a Promise.
* Once the module is completely loaded, the Promise is fulfilled with it.

```javascript
const moduleSpecifier = './dir/someModule.js';
import(moduleSpecifier).then(someModule => {
    ...
});
```

Features:

* The operator is used like a function (but actually `import()` is an operator).
* If `import()` is used in a module, it can occur anywhere at any level, and is not hoisted.
* `import()` can be used from scripts, not just from modules.
* `import()` accepts arbitrary strings, not just static string literals.
* The presence of `import()` in the module does not establish a dependency which must be fetched and evaluated before the containing module is evaluated.
* `import()` does not establish a dependency which can be statically analysed.
* `import()` follows the ES modules rules: singleton, specifiers, CORS etc.
* The order of used `import()` in the code doesn’t have anything in common with the order they are resolved.
* The dynamic import executes a script as a module, providing its own context which is different from the global.
* `import()` specifier is always related to the file it's called.

## Conditional loading of modules:

Use anywhere in the code:

```javascript
if (isLegacyPlatform()) {
    import(···).then(···);
}
```

Use variables to construct module declaration:

```javascript
const locale = "en";
import(`./utils_${locale}.js`).then(utils => {
  console.log("utils", utils);
  utils.default();
});
```

Loading modules on demand:

```javascript
button.addEventListener("click", event => {
  import("./dialogBox.js")
    .then(dialogBox => {
      dialogBox.open();
    })
    .catch(error => {
      /* Error handling */
    });
});
```

Features:

* you can use dynamic import for lazy or conditional loading and in user-depending action
* dynamic `import()` can be used anywhere in your scripts
* `import()` takes string literals and you can construct the specifier depending on your needs

## Use Promises patterns to load modules:

You can dynamically load multiple modules at the same time via `Promise.all()`:

```javascript
const modules = Promise.all([
    import('./module1.js'),
    import('./module2.js'),
    import('./module3.js'),
]);


modules.then(([module1, module2, module3]) => {
    ···
});
```

## Async functions and `import()`

```javascript
async function main() {
  const myModule = await import("./myModule.js");
  const { export1, export2 } = await import("./myModule.js");
  const [module1, module2, module3] = await Promise.all([
    import("./module1.js"),
    import("./module2.js"),
    import("./module3.js")
  ]);
}
main();
```

Dynamically load module using `async/await`:

```javascript
(async () => {
  const myModule = await import("./myModule.js");
})();
```

## References:

* [Native ES modules: dynamic `import()`](https://hospodarets.com/native-ecmascript-modules-dynamic-import)
* [Web fundamentals: dynamic `import()`](https://developers.google.com/web/updates/2017/11/dynamic-import)
