If you are coding some apps that are larger and more complicated than just "Hello World" or a calculator, you'll need to write a bunch of code. When your code file has more than 1000 lines, 20 functions, and a lot of variables, it's really hard to navigate, search, edit, and keep it in order. Here, modules can be of help. Do not repeat yourself, create functions and classes that help you do one or more tasks, then reuse them in other functions and classes.
How to use modules?
There are two main concepts related to modules:
Importing modules;
Exporting modules.
Importing helps you include additional JavaScript code in your code file. Exporting allows you to export a function, a class, or a variable from the module to use in other JavaScript codes.
Importing modules
require()To get a module in your application, you should import it into the main file. In CommonJS you can do it with the require() function. In most cases, declarations of imported modules are placed at the top of the file you're working on. Then you can access the imported modules later.
In this example, an imported built-in Node.js module is called url. The url module can parse URL strings and provide information on them.
// index.js
const url = require('node:url');
console.log(url.parse('https://jsonplaceholder.typicode.com/posts/1'));$ node index.js
# It will returns the parsed Url object:
# Url {
# protocol: 'https:',
# slashes: true,
# auth: null,
# host: 'jsonplaceholder.typicode.com',
# port: null,
# hostname: 'jsonplaceholder.typicode.com',
# hash: null,
# search: null,
# query: null,
# pathname: '/posts/1',
# path: '/posts/1',
# href: 'https://jsonplaceholder.typicode.com/posts/1'
# }require() is a function that belongs only to CommonJS modules. CommonJS is a system for organizing JavaScript code. The require() function needs a module name or a path in it. In the case above the name of a built-in Node.js module called url was passed.
Now, let's try to import your module. For example, create the main file named index.js and a dogBark.js module with a function that returns an actual dog barking. They're both in the same directory. To export the function from the module, use module.exports. We'll return to exporting in the next section.
/*
* ~/project
* |- dogBark.js
* |- index.js
*/
//dogBark.js
module.exports = function dogBark() {
return 'Bark! Bark!';
};//index.js
const dogBark = require('./dogBark.js');
console.log(dogBark());$ node index.js
# Bark! Bark!So, the dogBark.js function was exported to be used in other modules. Then dogBark.js was imported to the index.js file and used inside the console.log() function to get command prompt output.
In your projects, always use a relative path to the module you want to use. In CommonJS modules, you can use an extension or not. require('./dogBark') and require('./dogBark.js') return the same result.
Generally, it doesn't matter how you'll name the required module, but it might be a good idea to name it the same as the file or class name in it.
Exporting module
module.exports = {}There are a lot of possible ways to export something from a module. To export something, you need to place that something in an exports object of a module. It can be a function, a class, an object, a string, a number, an array, or a boolean.
// Functions
module.exports = function divider(x, y) {
return Math.ceil(x / y);
};
// Objects
module.exports = {
name: 'Roberto',
position: 'Space engineer',
};
// Strings and Numbers
module.exports = 'Hello';
module.exports = 3;
// Exporting existing class
class Cat { name='Larry' };
module.exports = new Cat();In the next example, let's create an Owl class as a module. We can give a name, a type, and a voice to our owl. And give it a few functions to communicate with an owl.
// owl.js
module.exports = new class Owl {
type = 'Bird';
voice = 'Owoo';
name = 'Hedwig'
whoIs() {
return this.type;
};
getVoice() {
return this.voice;
};
getName() {
return `My name is ${this.name}`;
};
};Now we can use the Owl class to get information from it.
// index.js
const Owl = require('./owl');
console.log('Information about owl: ', Owl);
console.log('Who is owl: ', Owl.whoIs());
console.log('What owl says: ',Owl.getVoice());
console.log('What is your name, Owl: ',Owl.getName());$ node index.js
# Information about owl: Owl { type: 'Bird', voice: 'Owoo', name: 'Hedwig' }
# Who is owl: Bird
# What owl says: Owoo
# What is your name, Owl: My name is HedwigWhile using IDE or a code editor, you can "fall" into the module: just click on the name of the module while pressing Ctrl.
Modules have shortcut methods. For example, module.exports.catName = 'Larry' will return an object { catName: 'Larry' }.
Other file extensions
CommonJS modules can have different file extensions:
.jsis a JavaScript file;.cjsis a JavaScript module file;.jsonis a JavaScript Object Notation file;.mjsis an ECMAScript module file.
.js, .cjs, and .json extensions can be imported by the require() function, and you can use them like always in CommonJS. The fourth file extension should be imported by another function. You'll learn more about the ECMAScript modules later.
// index.js
const parrot = require('./parrot.cjs');
const cat = require('./cat.json');
const tiger = require('./tiger.js');
console.log([
parrot,
cat,
tiger
]);$ node index.js
# Output:
# [
# { name: 'Garry', color: 'green', age: 2 },
# { name: 'Jason', color: 'peach', age: 10 },
# { name: 'David', color: 'orange', age: 15 }
# ]When you use a package manager like npm, you can choose the type of module in your package.
{
"name": "commonjs-modules-lession",
"version": "1.0.0",
"main": "index.js",
"type": "commonjs", /*the other type is "module", it will be ECMAScript.*/
"scripts": {
"test": "node index.js"
}
}When a module was imported via the require() function, it's a CommonJS module. If it was imported via import, it's an ECMAScript module. You have to use only one module type.
Be careful while installing npm packages. If your project is based on CommonJS modules, be sure that the package you've downloaded can be imported as a CommonJS module via the require() function.
Module object
Inside the module, you can access module object information. You can get a filename, a path, parent modules, child modules, a module ID (fully resolved path in most cases), and a module path.
Take a look at this example below. Try it yourself.
// parrot.cjs
module.exports = {
name: 'Garry',
color: 'green',
age: 2
}
console.log(module.parent); // returns parent module that uses current module
console.log(module.children); // returns current module child modules (empty array in this case)
console.log(module.filename); // returns current module filename
console.log(module.path); // returns current file path without the filenameConclusion
Modules can be imported and exported. CommonJS has three main file extensions: .js, .cjs, and .json. You can't access a parent module from a child module (except for the module object data). However, you can access the module object and information about the current module, its children, and its parents. Modules have to be reusable and encapsulated. Use modules to organize and structure code in your project, it's quite easy!