Javascript tips — Dynamically importing ES modules with import()

Leonardo Bruno Lima
2 min readApr 18, 2018
Photo by Lora Ohanessian on Unsplash

Today I will talk about a possible great news. The introduction of a feature that allow us to dynamically importing module. It’s in stage 3 of proposal and many changes can be made, but the idea will remain the same.

If you are interested in know better about the TC39 process, you can read more here, and you can read more about the proposal itself here.

This proposal was made by Domenic Denicola and it enables dynamic loading of ECMAScript modules. Currently ECMAScript modules are static: you must specify what you want to import and export at compile time and this static structure of imports is enforced syntactically in two ways. Let’s see an example:

import * as myModule from './myModule.js';

This import declaration can only appear at the top level of a module, which prevents you from importing modules inside any other statements and also the module specifier './myModule.js' cannot be computed at runtime.

With import() operator we can load modules dynamically. Let’s see some examples:

const myModule = './myModule.js';
import(myModule)
.then(x => x.someMethod());

The operator is used like a function and the parameter is a string with a module specifier (path of the module). In contrast to the current “import”, the parameter can be any expression whose result can be coerced to a string and the result of the “function call” is a Promise. Once the module is loaded, the Promise is fulfilled with it and you are good to go.

The import() works like a function, but it is an operator: In order to resolve “module specifiers” relatively to the current module, it needs to know from which module it is invoked.

Ok, once this feature was released, we can do many interesting things, for example: some web app feature doesn’t have to be present when app starts and it can be loaded on demand. Let’s see an example:

btnUpdate.addEventListener('click', event => {
import('./myModule.js')
.then(x => {
x.someInterestedFunction();
})
.catch(error => {
/* Error handling */
})
});

We can load some modules depending on whether a condition is true. For example:

if (someCondition()) {
import('./myModule.js')
.then(x => x.someMethod());
}

You can compute module specifiers like this:

import(`messages_${getCurrentLanguage()}.js`)
.then(...);

There are another details I could talk about, but I will wait for the stage 4 in order to write a new post with the final features and tips.

That’s all folks,

Thanks for reading!

--

--