Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In the `import` syntax of ES6, how is a module evaluated exactly?

Let's say we have four modules, A, B,C and D

In module A:

console.log("A evaluated") function AClass {   console.log("A constructor") } var aObj = new AClass() export default aObj; 

In module B:

import aObj from A export default "B" 

In module C:

import aObj from A export default "C" 

In module D:

import b from B import c from C import aObj from A 

So when module D is evaluated, how many times will the A evaluated and A constructor be printed in the console?

Is this behavior described in ES6 standard? What should I do if I want a module to be evaluated ONLY ONCE no matter how many times is imported directly or indirectly? Does anyone have any ideas about this?

like image 556
Hanfei Sun Avatar asked Apr 12 '16 06:04

Hanfei Sun


People also ask

What is ES6 module syntax?

An ES6 module is a file containing JS code. There's no special module keyword; a module mostly reads just like a script. There are two differences. ES6 modules are automatically strict-mode code, even if you don't write "use strict"; in them. You can use import and export in modules.

How can I conditionally import an ES6 module?

To conditionally import an ES6 module with JavaScript, we can use the import function. const myModule = await import(moduleName); in an async function to call import with the moduleName string to import the module named moduleName . And then we get the module returned by the promise returned by import with await .

What is import and export in ES6?

With the help of ES6, we can create modules in JavaScript. In a module, there can be classes, functions, variables, and objects as well. To make all these available in another file, we can use export and import. The export and import are the keywords used for exporting and importing one or more members in a module.

How do imports work in JavaScript?

The static import declaration is used to import read-only live bindings which are exported by another module. The imported bindings are called live bindings because they are updated by the module that exported the binding, but cannot be modified by the importing module.


1 Answers

When the D module is executed, the console will print this message:

A evaluated A constructor 

Which means that the A module was evaluated only once, even if it was imported multiple times by other modules.

The evaluation rules for ES6 modules is the same as for commonjs format:

  • A module is a piece of code that is executed once it is loaded. It means that if a module is not included in the main bundle, it will not be evaluated
  • Modules are singletons. If a module is imported multiple times, only a single instance of it exists and it is evaluated only once at load

The behaviour of importing the same instance of the module is described HostResolveImportedModule section of the ECMAScript 6 specification.
It mentions:

This operation (import operation) must be idempotent if it completes normally. Each time it is called with a specific referencingModule, specifier pair (import <a> from <source>) as arguments it must return the same Module Record instance.

The behaviour of single time evaluation of the module is described in ModuleEvaluation, point 4 and 5 using Evaluated boolean flag.
Each module has Evaluated flag which makes sure to evaluate the module code only once.

like image 113
Dmitri Pavlutin Avatar answered Oct 16 '22 04:10

Dmitri Pavlutin