Dynamic import ( https://github.com/tc39/proposal-dynamic-import )

Author

  • Domenic Denicola

Motivation and use cases

The existing syntactic forms for importing modules are static declarations.

They accept a string literal as the module specifier, and introduce bindings into the local scope via a pre-runtime “linking” process.

This is a great design for the 90% case, and supports important use cases such as static analysis, bundling tools, and tree shaking.

However, it’s also desirable to be able to dynamically load parts of a JavaScript application at runtime . This could be because of factors only known at runtime (such as the user’s language), for performance reasons (not loading code until it is likely to be used), or for robustness reasons (surviving failure to load a non-critical module).

Such dynamic code-loading has a long history, especially on the web, but also in Node.js (to delay startup costs).

The existing import syntax does not support such use cases.

Truly dynamic code loading also enables advanced scenarios, such as racing multiple modules against each other and choosing the first to successfully load.

Proposed solution

This proposal adds an import(specifier) syntactic form, which acts in many ways like a function (but see below). It returns a promise for the module namespace object of the requested module, which is created after fetching, instantiating, and evaluating all of the module’s dependencies, as well as the module itself.

Here specifier will be interpreted the same way as in an import declaration (i.e., the same strings will work in both places).

However, while specifier is a string it is not necessarily a string literal; thus code like import( ./language-packs/${navigator.language}.js ) will work—something impossible to accomplish with the usual import declarations.

import() is proposed to work in both scripts and modules.

This gives script code an easy asynchronous entry point into the module world, allowing it to start running module code.

Like the existing JavaScript module specification, the exact mechanism for retrieving the module is left up to the host environment (e.g., web browsers or Node.js).

This is done by introducing a new host-environment-implemented abstract operation, HostPrepareImportedModule, in addition to reusing and slightly tweaking the existing HostResolveImportedModule.

(This two-tier structure of host operations is in place to preserve the semantics where HostResolveImportedModule always returns synchronously, using its argument’s [[RequestedModules]] field. In this way, HostPrepareImportedModule can be seen as a mechanism for dynamically populating the [[RequestedModules]] field. This is similar to how some host environments already fetch and evaluate the module tree in ahead of time, to ensure all HostResolveImportedModule calls during module evaluation are able to find the requested module.)

Example

Here you can see how import() enables lazy-loading modules upon navigation in a very simple single-page application:

Note the differences here compared to the usual import declaration:

  • import() can be used from scripts, not just from modules.

  • If import() is used in a module, it can occur anywhere at any level, and is not hoisted.

  • import() accepts arbitrary strings (with runtime-determined template strings shown here), 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 analyzed. (However, implementations may still be able to perform speculative fetching in simpler cases like import(“./foo.js”).)

Importation dynamique

async function doSomething(){
   const lib = await import('heavylib');

   //do something with *lib*
}

doSomething();

L’importation dynamique nous permet de charger des bibliothèques/modules externes lorsque nous en avons besoin.

Auparavant, nous avions l’habitude de charger les bibliothèques/modules en haut, bien que tous les modules ne soient pas nécessaires immédiatement.

Certains devaient l’être plus tard dans le programme.

Le principal avantage de cette méthode est que nous pouvons réduire le temps de chargement du site web. Et c’est ce que la plupart des propriétaires de sites web veulent avoir. Il peut être un outil utile lorsque la performance est le principal objectif de votre projet.

Dynamic Import ( https://medium.com/javascript-in-plain-english/new-features-in-es2020-you-should-check-b4974d9d7edc )

Now, you can import a file dynamically.

import { max } from '../math.js';

const nums = [1, 2, 3];
max(...nums); // 3

This has been the way we could import a file.

And the JavaScript engine reads the modules in the file and bring them into the file where those modules are called.

But now, you can do this as follows .

1 const numbs = [1, 2, 3];if (numbs.length) {
2   const math = '../math';
3   import(math)
4     .then(module => {
5       module.max(...numbs);
6     })
7 }

A dynamic import returns a promise. Which means you can write it this way as well.

const math = '../math.js';
const module = await import(math);
module.max(...numbs);

Why this feature is good is that you can use a dynamic import in a regular JavaScript code like the example above.

Articles

www.freecodecamp.org

Dynamic imports in JavaScript give you the option to import JS files dynamically as modules in your application natively.

This is just like how you do it with Webpack and Babel at the moment.

This feature will help you ship on-demand-request code, better known as code splitting, without the overhead of webpack or other module bundlers.

You can also conditionally load code in an if-else block if you like.

The good thing is that you actually import a module, and so it never pollutes the global namespace.

if (mycondition) {
    const module = await import('.dynamicmodule.js')
    module.addNumbers(3, 4, 5) // WIN !
}

https://www.jesuisundev.com

ES2020 accueille également les Dynamic Import.

C’est une feature qui est utilisable depuis un moment dans pas mal de browser.

Toujours expérimental en node.

C’est fort possible que tu l’utilises déjà. Elle est désormais officiellement dans la spécification de cette année.

Pour comprendre ce que c’est cette feature, il faut qu’on s’intéresse à la façon traditionnelle d’importer un module dans notre application Javascript. On le fait de façon static, et surtout on preload le module peut importe si on en a besoin ou pas.

import { myModule } from '/path/moduleFile.js';

const superToto = false;

if (superToto) {
  myModule.doStuff();
}

Ici de façon static le module est importé dans la page. Ensuite, comme le flag superToto est négatif, la fonction du module ne sera pas utilisée.

Mais on a quand même le module preloadé dans ta page.

Dynamic Import vient régler ce problème. Tu peux importer un module à la demande ! Ça te permet donc de faire du lazy-loading en esquivant le coût du chargement, du parsing et de la compilation. Tout se fera à la volée seulement si l’utilisateur en a vraiment besoin. C’est fait de façon asynchrone, donc tu peux soit gérer ça avec des promesses ou avec async/await comme ci-dessous.

const superToto = true;

if (superToto) {
  const { doStuff } = await import('/path/moduleFile.js');
  doStuff();
}

https://exploringjs.com/impatient-js

https://github.com/systemjs/systemjs