require and module.exports

Posted by admin at March 20, 2020

Node provides a built-in module mechanism which works with the require() method and the module.exports global object. To demonstrate how require and module.exports work, let’s say we have two files account-service.js and utility.js.

The utility.js has some generic methods and objects which we use in many projects and applications. In this example, we will import those generic methods into account-service.js.

Here’s the code of utility.js in which we expose code to account-service.js (or any other program) by assigning it to a special global module.exports:module.exports = function(numbersToSum) { let sum = 0, i = 0, l = numbersToSum.length; while (i < l) { sum += numbersToSum[i++] } return sum }

The main program (account-service.js) imports the utility module and executes it to find out the total balance:const sum = require('./utility.js') let checkingAccountBalance = 200 let savingsAccountBalance = 1000 let retirementAccountBalance = 20000 let totalBalance=sum([checkingAccountBalance, savingsAccountBalance, retirementAccountBalance] ) console.log(totalBalance)

The account-service.js can be run from the same folder where the file is located with node account-service.js. The code will import the utility.js and invoke sum(). Thus, the result will be output of the total balance.

Skip to main content

require() can be used to import many different types of modules, not just for local node.js files. You can use require() to do the following:

  • Import core modules/packages, e.g., const filesystem = require('fs')
  • Import npm modules/packages, e.g., const express = require('express')
  • Import single file in a project, e.g., const server = require('./boot/server.js')
  • Import single JSON files, e.g., const databaseConfigs = require('./configs/database.json')
  • Import folders in a project (an alias for importing an index.js in that folder), e.g.,const routes = require('./routes')

More examples:const filesystem = require('fs') // core module const express = require('express') // npm module const server = require('./boot/server.js') // server.js file with a relative path down the tree const server = require('../boot/server.js') // server.js file with a relative path up the tree const server = require('/var/www/app/boot/server.js') // server.js file with an absolute path const server = require('./boot/server') // file if there's the server.js file const routes = require('../routes') // index.js inside routes folder if there's no routes.js file const databaseConfigs = require('./configs/database.json') // JSON file

Using require() with local files

To use require() with local files, specify the name string (the argument to require()) of the file you are trying to import. In general, start the name string with a . to specify that the file path is relative to the current folder of the node.js file or a .. to specify that the file path is relative to the parent directory of the current folder. For example, const server = require('./boot/server.js') imports a file named server.js which is in a folder named boot that is in the current folder relative to the code file in which we write require().

Using require() with npm or core modules/packages

To use require() with an npm or core module/package, enter the module/package name as the name string. There should not be . or .. in the name string. For example, const express = require('express') imports a package named express. The package is in the node_modules folder in the root of the project if it’s an installed npm package, and in the system folder if it’s a core Node module (exact location depends on your OS and how you installed Node).

As you can see, require() is very versatile and can be used in many cases.

Skip to main content

require() caches the results based on the filename and path. Any code outside of the module.exports assignment will be run just once during the process execution. For example, the following code is a module named utility.js and it has some code outside of module.exports:console.log('This will be printed just once') module.exports = function(numbersToSum) { let sum = 0, i = 0, l = numbersToSum.length; while (i < l) { sum += numbersToSum[i++] } return sum }

The account-service.js file uses our utility.js module:const sum = require('./utility.js') let checkingAccountBalance = 200 let savingsAccountBalance = 1000 let retirementAccountBalance = 20000 let totalBalance=sum([checkingAccountBalance, savingsAccountBalance, retirementAccountBalance] ) console.log(totalBalance)

This is app.js which imports two files. AYou can also use require() to run code without assigning the result to anything (line 2).const sum = require('./utility.js') require('./account-service.js') let checkingAccountBalance = 200 let savingsAccountBalance = 1000 let retirementAccountBalance = 20000 retirementAccountBalance = 40000 let totalBalance=sum([checkingAccountBalance, savingsAccountBalance, retirementAccountBalance] ) console.log(totalBalance)

In app.js when you import the module utility.js two or more times (directly and indirectly via account-service.js), the code in utility.js which prints This will be printed just once (it’s outside the module.exports) will be run just once despite the fact that the function module.exports (which we exported) is invoked twice: once in account-service.js and the second time in app.js.

Therefore, running app.js will result in its balance being printed twice, one time in account-service and another time in app.js, but the This will be printed just once console log only appears once:This will be printed just once 21200 41200

Why did the code outside module.exports run just once even though we imported the utility.js module twice (once directly and one indirectly via account-service.js)?

The reason is because Node.js will cache imports. The second time you require() the same file or a module, it’s not running the code. The results of the module are already there for you to use.

Just keep this behavior in mind and as a general rule, have all the logic exported in module.exports to avoid any unwanted behavior or conflicts.

Skip to main content

There are several patterns which developers can use to export functionality from a module:

  • Export a function: module.exports = function(ops) {...}
  • Export an object: module.exports = {...}
  • Export multiple functions: module.exports.methodA = function(ops) {...} which is the same as exports.methodA = function(ops) {...}
  • Export multiple objects: module.exports.objA = {...} which is the same as exports.objA = {...}

module.exports.name = ... or exports.name =... are used for multiple export points in a single file. They are equivalent to using module.exports = {name: ...}.

Be careful! exports = ... (without module) is not a valid module/export statement.

Let’s take a look at how to export and use multiple functions. We begin with a monolithic program named print-greetings.js that has all the logic to print hello in three languages.

print-greetings.js:// greeting methods var sayHelloInEnglish = function() { return 'Hello' } var sayHelloInSwedish = function() { return 'Hej' } var sayHelloInTatar = function() { return 'Isänme' } console.log('Swedish ' + sayHelloInSwedish() + ' & English ' + sayHelloInEnglish() + ' & Tatar ' + sayHelloInTatar())

You can see that if you add 50 more languages, this file will start to become difficult to manage. If you wanted to use the sayHello... methods in other files, then this monolithic file wouldn’t work well either. Let’s modularize the program by putting the translation methods into their own module named greetings.js.

Exporting methods using exports.methodA = function(ops) {...}

We can export the greeting methods by individually defining the greeting methods on the exports object.

greetings.js:exports.sayHelloInEnglish = function() { return 'Hello' } exports.sayHelloInSwedish = function() { return 'Hej' } exports.sayHelloInTatar = function() { return 'Isänme' }

Exporting methods using module.exports = {...}

We can also export the greeting methods by setting module.exports equal to an object that contains the greeting methods.

greetings.js:module.exports = { sayHelloInEnglish() { return 'Hello' } sayHelloInSwedish() { return 'Hej' } sayHelloInTatar() { return 'Isänme' } }

Regardless of the export pattern you use, module.exports will end up being an object with three greeting methods.

Importing with require()

Next, we can edit print-greetings.js to import methods from greetings.js using require(). The require() method returns whatever was exported from the imported module. In this case, the require() method returns an object with three greeting methods and that object gets assigned to the greetings variable. The greetings methods are then accessible through the greetings variable.

printGreetings.js:var greetings = require('./greetings.js') console.log('Swedish ' + greetings.sayHelloInSwedish() + ' & English ' + greetings.sayHelloInEnglish() + ' & Tatar ' + greetings.sayHelloInTatar())

Skip to main content

Core Modules

Core modules come with Node.js and don’t need to be installed. Core modules provide low-level functionality and helper methods. They allow Node.js to work with the filesystem, networking, binary data, streams, spawn external processes, parse query strings, file paths and URLs, and perform other helpful tasks such as creating HTTP(S) agents/clients and servers.

Here’s the list of main core modules:

  • fs: module to work with the file system, files and folders
  • path: module to parse file system paths across platforms
  • querystring: module to parse query string data
  • net: module to work with networking for various protocols
  • stream: module to work with data streams
  • events: module to implement event emitters (Node observer pattern)
  • child_process: module to spawn external processes
  • os: module to access OS-level information including platform, number of CPUs, memory, uptime, etc.
  • url: module to parse URLs
  • http: module to make requests (client) and accept requests (server)
  • https: module to do the same as http only for HTTPS
  • util: various utilities including promosify which turns any standard Node core method into a promise-base API
  • assert: module to perform assertion based testing
  • crypto: module to encrypt and hash information

There is no need to install or download core modules. To include them in your application, all you need is to use the following syntax:const http = require('http') //replace `http` with the core module you want to use

Skip to main content

fs handles file system operations such as reading to and writing from files. There are synchronous and asynchronous methods in the library. Some of the methods include the following:

  • fs.readFile(): reads files asynchronously
  • fs.writeFile(): writes data to files asynchronously

Comments

Write a Reply or Comment

Your email address will not be published. Required fields are marked *