Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Victor Magarlamov
Victor Magarlamov

Posted on

     

ES modules

The best definition I've ever seen about ES modules is: "modules allow us to import and export stuff". Exactly! We use modules for import/export components, classes, help methods, variables and other stuff. They help us to organize our code.

In fact Module is one of the popular design pattern that allows encapsulate the code. Let's look at the implementation of this pattern.

constModule=(function(){let_privateVariable;letpublicVariable;function_privateMethod(){}functionpublicMethod(){}return{publicVariable,publicMethod,};})();

We have there ananonymous closure that creates anenclosed scope withprivate andpublic methods / variables and asingleton object that get us an access to the public properties of the module.

Now let’s look at ES modules. Imagine, we have some modules...

// module Aconsole.log(a)
// module Bconsole.log(b)
// module Cconsole.log(c)

Modules first!

When we import these modules into a file and execute it, the modules will beinvoked first.

import*asafrom./a.jsimport*asbfrom./b.jsimport*ascfrom./c.jsconsole.log(index);

Output:

abcindex

Modules are evaluated only once!

The module will be evaluated only once and it does not matter how many files are module dependent.

// module Aimport*ascfrom./c.jsconsole.log(a)
// module Bimport*ascfrom./c.jsconsole.log(b)
import*asafrom./a.jsimport*asbfrom./b.jsconsole.log(index);

Output:

cabindex

It works thanks toModule Map. When a module is imported, amodule record is created and placed in the Module Map. When another module try to import this module, the module loader will look up in the Module Map first. Thus we can have asingle instance of each module.

Another demonstration of this idea.

// module Aimport*asbfrom./b.jsconsole.log(a)
// module Bimport*asafrom./a.jsconsole.log(b)
import*asafrom./a.jsimport*asbfrom./b.jsconsole.log(index);

Output:

baindex

The module loading process takes several steps:

  1. Parsing - if there are any errors in your module, you will know about it first
  2. Loading - if there are any imports in your module, they will be recursively imported (and themodule graph will be built).
  3. Linking - creating a module scope
  4. Run time - running a module body

So, let’s look at our previous example step by step.

->import*asafrom'./a.js'|->creatingamodulerecordforfile'./a.js'intotheModulemap|->parsing|->loading-import*asbfrom'./b.js'|->creatingamodulerecordforfile'./b.js'intotheModulemap|->parsing|->loading->import*asafrom'./a.js'|->amodulerecordforfile'./a.js'alreadyexistintheModuleMap|->linked|->run|->linked|->run

This case is an example of thecircular module dependency. And if we try to call some variable from the A module in the B module, we will get a Reference Error in this case.

Module properties are exported by reference!

Let’s add a public variable into the A module.

// module Aexportletvalue=1;exportfunctionsetValue(val){value=val;}

Now let’s import the A module into the B module...

// module Bimport*asafrom./a.jsa.setValue(2);

...and look at the value from the C module.

// module Cimport*asafrom./a.jsconsole.log(a.value);

Output will be '2'. Pay attention to one remarkable feature of the module - we cannot directly change the value property in module B. The 'value' property isread-only, and we get a TypeError.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Joined

More fromVictor Magarlamov

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp