Exporting and Requiring Functions and Variables with module.exports
As an example, here is a new module that gives book recommendations. In the code below, I have defined a variable as well as a few functions. Later, we will access the functionality of these book recommendations from another module.
// book_recommendations.js
// stores the favorite author in a constant variable
const favoriteAuthor = { name: "Ken Bruen", genre: "Noir", nationality: "Irish" };
// returns the favorite book
function favoriteBook() {
return { title: "The Guards", author: "Ken Bruen" };
}
// returns a list of good books
function getBookRecommendations() {
return [
{id: 1, title: "The Guards", author: "Ken Bruen"},
{id: 2, title: "The Stand", author: "Steven King"},
{id: 3, title: "The Postman Always Rings Twice", author: "James M. Cain"}
];
}
// exports the variables and functions above so that other modules can use them
module.exports.favoriteAuthor = favoriteAuthor;
module.exports.favoriteBook = favoriteBook;
module.exports.getBookRecommendations = getBookRecommendations;
We’ve added all the variables and functions we would like to export to module.exports as properties of the object. We have just accomplished our goal of exporting these functions and variables from the book_recommendations module.
Now we can see how easy it is to import anything using require. Going back to our book_recommendations module, we can import it and access the functions it exports. This is shown in the next code listing.
Create a new module as shown below, then run it as shown earlier to see it using the functions defined in the imported book_recommendations module.
// birthday_gifts.js
// import the book recommendations module
let books = require('./book_recommendations');
// gets some music recommendations as well
let musicAlbums = [
{ artist: "The Killers", title: "Live From The Royal Albert Hall" },
{ artist: "Eminem", title: "The Marshall Mathers LP" }
];
// the two best items from each category
let topIdeas = function() {
return [musicAlbums[0], books.favoriteBook()];
}
// outputs a message specifying the customer's recommended gifting items
let gifts = function() {
console.log("Your recommended gifts are:\n");
console.log("######MUSIC######");
for (let i = 0, len = musicAlbums.length; i < len; i++) {
console.log(musicAlbums[i].title + " by " + musicAlbums[i].artist);
}
console.log("######BOOKS######");
let recommendedBooks = books.getBookRecommendations();
for (let i = 0, len = recommendedBooks.length; i < len; i++) {
console.log(recommendedBooks[i].title + " by " + recommendedBooks[i].author);
}
console.log("\n\nYours");
console.log("Shop Staff\n*************");
console.log("P.S. If you have a limited budget, you should just get the music album " + topIdeas()[0].title + " and the book " + topIdeas()[1].title + ".");
}
console.log("Welcome to our gift shop.\n");
// Get the gifts
gifts();
Exporting And Requiring Classes with module.exports
In addition to functions and variables, we can also use module.exports to export other complex objects, such as classes.
In the following example, we create a Cat class which contains a name and age for Cat objects. Then we export the Cat class by attaching it as a property of the module.exports object. As you can see, this is not that different from how we exported functions and variables before.
// cat.js
// constructor function for the Cat class
function Cat(name) {
this.age = 0;
this.name = name;
}
// now we export the class, so other modules can create Cat objects
module.exports = {
Cat: Cat
}
Now we can access this Cat class by importing the cat module. Once that’s done, we can create new Cat objects and use them in the importing module as shown in the following example. Again, you should try running this code with node cat_school.js to see the names and ages of the new cats at your command prompt.
// cat_school.js
// import the cat module
let cats = require('./cat');
let Cat = cats.Cat;
// creates some cats
let cat1 = new Cat("Manny");
let cat2 = new Cat("Lizzie");
// Let's find out the names and ages of cats in the class
console.log("There are two cats in the class, " + cat1.name + " and " + cat2.name + ".");
console.log("Manny is " + cat1.age + " years old " + " and Lizzie is " + cat2.age + " years old.");
As we just saw, exporting a class can be accomplished by attaching the class as a property of the module.exports object. First, we created a class using a constructor function. Then we exported the class using module.exports. To use the class, we then required it in another module, and then created instances of the class.
An Alternative: Using the Shorthand exports VS module.exports
While we can continue assigning things for export as properties of module.exports, there exists a shorthand way of exporting things from the module. This shorthand way involves using just exports instead of module.exports. There are some differences between the two. The key thing to notice here, however, is that you must assign your new values as properties of the shortcut export object, and not assign objects directly to overwrite the value of export itself.
Here is an example in which I use this shorthand way to export a couple of objects from a module named film_school.
// film_school.js
// a beginner film course
let film101 = {
professor: 'Mr Caruthers',
numberOfStudents: 20,
level: 'easy'
}
// an expert film course
let film102 = {
professor: 'Mrs Duguid',
numberOfStudents: 8,
level: 'challenging'
}
// export the courses so other modules can use them
exports.film101 = film101;
exports.film102 = film102;
Notice how we are assigning the objects as, for example, exports.film101 = … instead of exports = film101. That later assignment would not export the variable, but mess up your shortcut exports entirely.
The exporting done in the shorthand way above, could have been achieved in the long-form way we have used with module.exports using the following lines for the exporting.
// export the courses so other modules can use them
module.exports.film101 = film101;
module.exports.film102 = film102;
We could also export the two objects by assigning an object directly to module.exports but this would not work with exports.
// export the courses so other modules can use them
module.exports = {
film101: film101,
film102: film102
}
The two are very similar, and rightly so. These are two ways of achieving the same thing, but exports can trip you up if you assign an object to exports the way you would assign to module.exports.
Differences Between Node.js Modules and ES6 Modules
The modules used in Node.js follow a module specification known as the CommonJS specification. The recent updates to the JavaScript programming language, in the form of ES6, specify changes to the language, adding things like new class syntax and a module system. This module system is different from Node.js modules. A module in ES6 looks like the following:
// book.js
const favoriteBook = {
title: "The Guards",
author: "Ken Bruen"
}
// a Book class using ES6 class syntax
class Book {
constructor(title, author) {
this.title = title;
this.author = author;
}
describeBook() {
let description = this.title + " by " + this.author + ".";
return description;
}
}
// exporting looks different from Node.js but is almost as simple
export {favoriteBook, Book};
To import this module, we’d use the ES6 import functionality, as follows.
// library.js
// import the book module
import {favoriteBook, Book} from 'book';
// create some books and get their descriptions
let booksILike = [
new Book("Under The Dome", "Steven King"),
new Book("Julius Ceasar", "William Shakespeare")
];
console.log("My favorite book is " + favoriteBook + ".");
console.log("I also like " + booksILike[0].describeBook() + " and " + booksILike[1].describeBook());
ES6 modules look almost as simple as the modules we have used in Node.js, but they are incompatible with Node.js modules. This has to do with the way modules are loaded differently between the two formats. If you use a compiler like Babel, you can mix and match module formats. If you intend to code on the server alone with Node.js, however, you can stick to the module format for Node.js which we covered earlier.
Reference
how-to-use-module-exports-in-node-js
Express.js on steroids: an OOP way for organizing Node.js project
react-facebook-login-tutorial-example
react-facebook-login-tutorial-example – StackBliz