ES6 Modules

Modules are the piece or chunk of a JavaScript code written in a file. JavaScript modules help us to modularize the code simply by partitioning the entire code into modules that can be imported from anywhere. Modules make it easy to maintain the code, debug the code, and reuse the piece of code. Each module is a piece of code that gets executed once it is loaded.

Modules in ES6 is an essential concept. Although it is not available everywhere, but today we can use it and can transpile into ES5 code. Transpilation is the process of converting the code from one language into its equivalent language. The ES6 module transpiler tool is responsible for taking the ES6 module and converts it into a compatible code of ES5 in the AMD (Asynchronous module definition is a specification for the JavaScript programming language) or in the CommonJS style.

During the build process, we can use Gulp, Babel, Grunt, or other transpilers for compiling the modules. The variables and functions in a module are not available for use unless the file exports them.

Exporting and Importing a Module

Exporting a Module

JavaScript allows us to export a function, objects, classes, and primitive values by using the export keyword. There are two kinds of exports:

  • Named Exports: The exports that are distinguished with their names are called as named exports. We can export multiple variables and functions by using the named export.
  • Default Exports: There can be, at most, one value that can be exported by using the default export.

Importing a Module

To import a module, we need to use the import keyword. The values which are exported from the module can be imported by using the import keyword. We can import the exported variables, functions, and classes in another module. To import a module, we simply have to specify their path.

When you import the named export, you must have to use the same name as the corresponding object. When you import the default export, we can use any name of the corresponding object.

Let us elaborate on these exports and imports.

Named Exports and Imports

Named exports are distinguished with their names. The class, variable, or any function which is exported by using the named export can only be imported by using the same name.

Multiple variables and functions can be imported and exported by using the named export.

Syntax

Let us see the syntax to use named export in class, function, or in a variable. Below we are showing how to individually export the class, variable, and function by using the named export.

Example
snippet
//Named export in class
class Nokia{
//properties
//methods
}
export {Nokia}; //Named export

//Named export in functions
function show(){
}
export {show};

//Named export in Variables
const a = 10;
export {a};

We can apply more than one named export in a module. We can use the syntax of multiple named exports in a module as follows:

Mobile.js

snippet
class Nokia{
//properties
//methods
}
function show(){
}
const a = 10;
export {Nokia, show};

Let us see how to import the named exports.

Importing the Named export

To import the bindings that are exported by another module, we have to use the static import statement. The imported modules are always in the strict mode, whether we declare them in strict mode or not.

Syntax

App.js

Example #1
snippet
import {Nokia, show} from './Mobile.js';

Importing all

If we want to import all of the export statements simultaneously, then we can import them individually.

But it will be hard when we have so many named exports. So, to make it easier, we can do it as follows:

snippet
import * as device from './Mobile.js'; // Here, the device is an alias, and Mobile.js is the module name.

Suppose, we have defined a class Nokia in the module Mobile.js, and if we want to use it then by using the alias, we can perform it as:

snippet
device.Nokia //if we have a class Nokia
device.show // if we have a function show
device.a // if we have a variable a

Let us try to understand the Named export and import within a single example.

We have to make two JavaScript modules to perform export and import. In the first module, we export the class, function, and variable. In the second module, we will import them by using the named import.

Example #2

Example - Named Export and Import

Here, we are creating two JavaScript modules in which the first JavaScript module is Mobile.js, and the second module name is App.js. We are also creating an HTML file Example.html. Then, we will execute this .html file in the server.

Next, we have to manually link the JavaScript file in the HTML file by using the src attribute in the <script></script> tag. But the module still will not work. To enable the module, we have to use the type = "module" in the <script></script> tag.

Example.html

snippet
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script type = "module" src = "App.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>ES6 Modules import and export</h1>
</body>
</html>

Mobile.js

snippet
class Display{
    show(){
        console.log("Hello World :)");
    }
}
function javaT(){
    console.log("Welcome to rookienerd");
}
export {Display,javaT};

App.js

snippet
import {Display,javaT} from "./Mobile.js";
const d = new Display();
d.show();
javaT();

Output

Run the above Example.html file in the live server. Then, open the terminal in the browser by using ctrl+shift+I. After the successful execution, you will get the following output:

ES6 Modules

Default Exports and Imports

We can have only one default export in a module. A default export can be imported with any name.

Syntax

Let us see the syntax to use default export in class, function, or in a variable. Below we are showing how to individually export the class, variable, and function by using the default export.

Unlike the named export, we cannot simultaneously make more than one export statement in default export.

Example
snippet
//Default export in class
class Nokia{
//properties
//methods
}
export default Nokia; //Default export

//Deafult export in functions
function show(){
}
export default show;

//Default export in Variables
const a = 10;
export default a;
Importing the Default export

To import the bindings that are exported by another module, we have to use the static import statement. The imported modules are always in the strict mode, whether we declare them in strict mode or not.

Example #1

Mobile.js

snippet
class Nokia{
    //properties
    //methods
}
export default Nokia;

App.js

snippet
import Nokia from './Mobile.js';
Example #2

Example - Default import and export

Example.html

snippet
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script type = "module" src = "App.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>ES6 Modules import and export</h1>
    <h2>Default import and export</h2>
</body>
</html>

Mobile.js

snippet
class Display{
        show(){
            console.log("Hello World :)");
            console.log("Default Import and Export Example");
        }
    }
    export default Display;

App.js

snippet
import Display from "./Mobile.js";
const d = new Display();
d.show();

Output

Run the above Example.html file in the live server. Then, open the terminal in the browser by using ctrl+shift+I. After the successful execution, you will get the following output:

ES6 Modules

ES6 Cyclic dependencies

Cyclic dependency is a direct or indirect relation between two or more modules that depend on each other. Such modules are known as the mutually recursive modules.

The modules in ES6 automatically supports the cyclic dependencies. Two modules, such as A and B, are cyclically dependent on each other if both A imports B and B imports A either transitively or indirectly.

Suppose we have three modules named A, B, and C. Their chain of dependencies is like A->B->C->A, i.e., A is dependent upon B; B is dependent upon C and C is dependent upon A.

CommonJS and some of the other libraries support the circular dependencies, but there is a problem with importing and using named exports from a circular dependent module.

ES6 solves this problem by sharing the bindings to the values rather than the values itself in the exports. It means the connection with the variables declared in the body of the module can be done. We can see the demonstration for the same in the following code:

Example

Example.html

snippet
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <script type = "module" src = "App.js"></script>
    <title>Document</title>
</head>
<body>
    <h1>ES6 Cyclic dependencies</h1>
</body>
</html>

Mobile.js

snippet
export let count = 0;
export function show() {
    count++;
}

App.js

snippet
import { show, count } from './Mobile.js';
console.log(count); 
show();
console.log(count);

Output

ES6 Modules
Related Tutorial
Follow Us
https://www.facebook.com/Rookie-Nerd-638990322793530 https://twitter.com/RookieNerdTutor https://plus.google.com/b/117136517396468545840 #
Contents +