ES6 Modules
When the ES6 version of JavaScript was released, it included a way of dividing your code into modules. Component based design calls for organizing application code into reusable parts. Modules can be thought of as components (and vice-versa). JavaScript frameworks, such as Vue and React, make heavy use of ES6 modules.
When you create an ES6 module, you use the export keyword to declare the parts of the module that can be used by other files (those files just have to 'import' the parts). The parts of a module that are not 'exported' can only be used within the module itself (just like the private members of a class).
Let's create a few ES6 modules. Start by creating a folder named es6-modules.
Now, add a file named index.html to the folder, and put this code in it:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Testing ES Modules</title>
<script type="module" src="main.js"></script>
</head>
<body>
<h1>This page is using ES6 Modules</h1>
</body>
</html>
Note that the TYPE attribute of the SCRIPT element is set to module. This means that main.js will be making use of ES6 modules.
Create a file named main.js (in the es6-modules folder). We'll add code to this file in a minute, but first we need to create a module that can be imported into it.
Inside the es6-modules folder, create a folder named modules. This will be the folder that contains all the modules we create for this activity.
There are different ways to go about creating modules, here are just a few:
- A module can consist of a single function
- A module can consist of a single class
- A module can consist of a collection of functions
There are other ways to go about creating modules, but we'll stick to the 3 in the list.
In the modules folder, create a file named function.js. This will be our first module, and it will consist of a single function.
Put this code in function.js:
export default function doSomething(){
alert("Doing something......");
}
It looks like a regular function, but it includes the export and default keywords. If you want to make a function available outside of the module, then you must 'export' it. If you create a module that consists of multiple functions, you may want to keep some of them private, so you wouldn't export those functions.
The default keyword basically means that this is the main 'thing' (usually an object, function, or class) that the module exports. Later in this tutorial, you'll see how to create a module that exports more than one function.
To import the default in main.js add this code:
import doIt from './modules/function.js'
doIt();
When you import a default, you can assign any variable name to it that you want, in this case I chose 'doIt'. Since the default happens to be a function, you can invoke it like so: doIt().
Note that you should include ./ in the path to your module. This is because if you are using NPM, then any path that doesn't start with ./ will be assumed to be a module that is in the node_modules folder.
To run the code for our module, load index.html in the browser, but make sure you are using a web server!. If you try to launch the page from the file system, it won't work. ES6 modules require that the pages using them are accessed via a web server.
Now, we'll create a module that consists of a single JavaScript class. Add a file named class.js to the modules folder. Then put this code inside the file:
export default class Person{
#name;
constructor(name){
this.#name = name;
}
sayHello(){
alert(`Hello, I'm ${this.#name}`);
}
}
Now update main.js to import and make use of this module, like so:
import doIt from './modules/function.js'
import Person from './modules/class.js'
doIt();
const p = new Person("Lu");
p.sayHello();
The import statements should all go at the top of main.js.
Note the curly braces in the import statement. If a module does not include the default keyword, then it will export an object that includes all the things that are 'exported' in the module (this may make more sense in a minute, when we create a module that exports multiple things).
The import statement for the Person class is actually using destructuring. We can talk about this in class if you want, just remind me.
Reload index.html in the browser to see the Person class in action.
Finally, we'll create a module that exports various functions. Create a file in the modules folder, and name it functions.js. Then put this code in it:
export function sayHello(){
alert("hello");
log("hello");
}
export function sayGoodBye(){
alert("bye");
log("bye");
}
// Note that we are not using the 'export' keyword before log() function
function log(msg){
console.log(msg);
}
Note that only two of the three functions are declared as exports. This means that the log() function is private, and cannot be imported into another file.
Now, update main.js import and use the functions, like so:
import doIt from './modules/function.js'
import Person from './modules/class.js'
import {sayHello, sayGoodBye} from './modules/functions.js'
doIt();
const p = new Person("Lu");
p.sayHello();
sayHello();
sayGoodBye();
Go ahead and reload index.html in the browser.
One thing that makes ES6 modules confusing for beginners is that there are different ways to set up the things that are exported.
For example, we could have set up functions.js to look like this:
function sayHello(){
alert("hello");
log("hello");
}
function sayGoodBye(){
alert("bye");
log("bye");
}
function log(msg){
console.log(msg);
}
export {sayHello, sayGoodBye}
With this approach, we declare the functions that we want to export at the bottom of the file.
Another thing that makes ES6 modules confusing for beginners is that it is relatively new, and it is just starting to replace the require() function that you may have seen in many NodeJS projects.
This is admittedly a very quick overview of ES6 modules, but it's important for you to get a little bit of a start with them becasue we'll see them used in many JavaScript frameworks such as React and Vue.
If you are insterested to learn more, checkout these links: