By Dmitri Pavlutin

Translation: Crazy geek

Dmitripavlutin.com/javascript-…

Reproduced without permission

Let’s start with a question.

The ES2015 module named Increment contains the following code:

// increment.js
let counter = 0;
counter++;

export default counter;
Copy the code

In the consumer module, import the above module increment twice:

// consumer.js
import counter1 from './increment';
import counter2 from './increment';

counter1; / / = >???
counter2; / / = >???
Copy the code

The question is: what are the contents of the variables counter1 and counter2 when the consumer module runs?

To answer this question, you first need to understand how JavaScript evaluates and imports modules.

1. Module evaluation

A good way to understand the inner workings of JavaScript is to look at its instructions.

According to the specification, each JavaScript module is associated with a module record. The module record has the Evaluate() method, which evaluates the module:


If the module has been successfully evaluated, undefined is returned; … Otherwise, all module dependencies for this module can be evaluated recursively, and then the module can be evaluated.


So the same module is evaluated only once.

Unfortunately, the problem does not stop there. How do I ensure that the same module is returned from two calls to import statements using the same path?

2. Resolve the import problem

The paths (also known as specifier) associated with specific module duties by HostResolveImportedModule () to perform operations.

import module from 'path';
Copy the code

According to the rules:


The realization of the HostResolveImportedModule must meet the following requirements:

  • The normal return value must beModule RecordAn instance of a concrete subclass of.
  • If thereferencingScriptOrModule, specifierStudent: Corresponding toModule RecordIf it does not exist or cannot be created, an exception must be thrown.
  • Use specific ones each timereferencingScriptOrModule, specifierWhen this operation is called as an argument, it must return the same if it completes normallyModule RecordInstance.

Let’s look at what’s happening in a way that’s easy to understand.

HostResolveImportedModule (referencingScriptOrModule, specifiers) is an abstract operation, The operation returns corresponding to ReferencingScriptOrModule, specifiers module:

  • parameterreferencingScriptOrModuleIs the current module, that is, the module to import.
  • parameterspecifierIs the correspondingimportThe string of the module path in the statement.

Finally, HostResolveImportedModule () from the same path import module, will import the same module:

import moduleA from 'path';
import moduleB from 'path';
import moduleC from 'path';

// moduleA, moduleB and moduleC are equal

moduleA === moduleB; // => true
moduleB === moduleC; // => true
Copy the code

It is interesting to note that specification is pointed out that the host (refers to the browser, the Node or anything to try to run JavaScript) must provide HostResolveImportedModule () implementation.

3. The answer

After reviewing the specification, you will know that the JavaScript module has been evaluated. In addition, when a module is imported from the same path, the same module instance is returned.

Let’s go back to the question.

The INCREMENT module is always evaluated once:

// increment.js
let counter = 0;
counter++;

export default counter;
Copy the code

No matter how many times the increment module is imported, the counter++ statement is executed only once. The default exported counter variable has a value of 1.

Now look at the Consumer module:

// consumer.js
import counter1 from './increment';
import counter2 from './increment';

counter1; / / = > 1
counter2; / / = > 1
Copy the code

Import Counter1 from ‘./increment’ and Import Counter2 from ‘./increment’ have the same path: ‘./increment’. So you will import the same module instance.

Finally, both the counter1 and Counter2 variables inside the consumer are equal to 1.

4. Conclusion

Detailed information on how to evaluate and import JavaScript modules can be found by simply examining the simple questions posed.

The rule is simple: the same module is evaluated only once, in other words, module-level actions are performed only once. If the evaluated module is imported again, the second evaluation is skipped and the resolved exported file is used.

If a module is imported multiple times but uses the same specifier (that is, path), the JavaScript specification ensures that you will get the same module instance.

Welcome to the front end public number: front end pioneer, free Vue tutorial.