Using Modules in Node.js
Node.js is an event-driven, server-side JavaScript environment. Node.js runs JS using the V8 engine developed by Google for use in their Chrome web browser. Leveraging V8 allows Node.js to provide a server-side runtime environment that compiles and executes JS at lightning speeds.
The Module System
This article covers the Node’s module system and the different categories of the Node.js modules.
Application Modularization
Like most programming languages, Node.js uses modules as a way of organizing code. The module system allows you to organize your code, hide information, and only expose the public interface of a component using module.exports.
Node.js uses the CommonJS specification for its module system:
- Each file is its own module, for instance, in the following example, jsand math.js are both modules
- Each file has access to the current module definition using the modulevariable
- The export of the current module is determined by the module.exportsvariable
- To import a module, use the globally available requirefunction
Take a look at a simple example:
// math.js file function add(a, b) { return a + b; } … … module.exports = { add, mul, div, }; // index.js file const math = require('./math'); console.log(math.add(30, 20)); // 50
To call other functions such as mul and div, use object destructuring as an alternative when requiring the module, for example, const { add } = require(‘./math’);. The code files for the section The Module System are placed at Code/Lesson-1/b-module-system.
Module Categories
You can place Node.js modules into three categories:
- Built-in (native) modules: These are modules that come with Node.js itself; you don’t have to install them separately.
- Third-party modules: These are modules that are often installed from a package repository. npm is a commonly used package repository, but you can still host packages on GitHub, your own private server, and so on.
- Local modules: These are modules that you have created within your application, like the example given previously.
Built-In Modules
These are modules that can be used straight away without any further installation. All you need to do is to require them. There are quite a lot of them, but here are a few that you are likely to come across when building web applications:
- assert: Provides a set of assertion tests to be used during unit testing
- buffer: To handle binary data
- child_process: To run a child process
- crypto: To handle OpenSSL cryptographic functions
- dns: To do DNS lookups and name resolution functions
- events: To handle events
- fs: To handle the filesystem
- httpor https: For creating HTTP(s) servers
- stream: To handle streaming data
- util: To access utility functions like deprecate (for marking functions as deprecated), format (for string formatting), inspect (for object debugging), and so on
For example, the following code reads the content of the lesson-1/temp/sample.txt file using the in-built fs module:
const fs = require('fs'); let file = `${__dirname}/temp/sample.txt`; fs.readFile(file, 'utf8', (err, data) => { if (err) throw err; console.log(data); });
npm – Third-Party Module Registry
Node Package Manager (npm) is the package manager for JavaScript and the world’s largest software registry, enabling developers to discover packages of reusable code. To install an npm package, you only need to run the npm install <package-name> command within your project directory.
Here’s a simple example. If you want to use a package (library) like request in your project, you can run the following command on your Terminal, within your project directory:
npm install request
To use it in your code, you should require it, like any other module:
const request = require('request'); request('http://www.example.com', (error, response, body) => { if (error) console.log('error:', error); // Print the error if one occurred else console.log('body:', body); // Print the HTML for the site. });
More details about npm can be found at https://docs.npmjs.com/. When you run the npm install <module-name> command on your project for the first time, the node_modules folder gets created at the root of your project.
Scanning for node_modules
It’s worth noting how Node.js goes about resolving a particular required module. For example, if a /home/tony/projects/foo.js file has a require call require(‘bar’), Node.js scans the filesystem for node_modules in the following order. The first bar.js that is found is returned as follows:
- /home/tony/projects/node_modules/bar.js
- /home/tony/node_modules/bar.js
- /home/node_module/bar.js
- /node_modules/bar.js
Node.js looks for node_moduels/bar in the current folder followed by every parent folder until it reaches the root of the filesystem tree for the current file. Note that the module foo/index.js can be required as foo, without specifying an index and will be picked by default.
Handy npm Commands
Now dive a little deeper into npm, by looking at some of the handy npm commands that you will often need:
- npm init: Initializes a Node.js project. This should be run at the root of your project and will create a respective jsonfile. This file usually has the following parts (keys):
- name: Name of the project.
- version: Version of the project.
- description: Project description.
- main: The entry-point to your project, the main file.
- scripts: This will be a list of other keys whose values will be the scripts to be run, for example, test, dev-server. Therefore, to run this script, you will only need to type commands such as npm run dev-server, npm run test, and so on.
- dependencies: List of third-party packages and their versions used by the project. Whenever you do npm install <package-name> –save, this list is automatically updated.
- devDependencies: List of third-party packages that are not required for production, but only during development. This will usually include packages that help to automate your development workflow, for example, task runners like gulp.js. This list is automatically updated whenever you do npm install <package-name> –save-dev.
- npm install: This will install all the packages, as specified in the jsonfile.
- npm install <package-name> <options>:
- The –saveoption installs the package and saves the details in the json file.
- The –save-devoption installs the package and saves the details in the json, under devDependencies.
- The –globaloption installs the package globally in the whole system, not only in the current system. Due to permissions, this might require running the command with administrator rights, for example, sudo npm install <package-name> –global.
- npm install <package-name>@<version>, installs a specific version of a package. Usually, if a version is not specified, the latest version will be installed.
- npm list: Lists the packages that have been installed for the project, reading from what is installed in node_modules.
- npm uninstall <package-name>: Removes an installed package.
- npm outdated: Lists installed packages that are outdated, that is, newer versions have been released.
Local Modules
You have already looked at how local modules are loaded from the previous example that had math.js and index.js.
Since JavaScript Object Notation (JSON) is such an important part of the web, Node.js has fully embraced it as a data format, even locally. You can load a JSON object from the local filesystem the same way you load a JavaScript module. During the module loading sequence, whenever a file.js is not found, Node.js looks for a file.json.
See the example files in lesson-1/b-module-system/1-basics/load-json.js:
const config = require('./config/sample'); console.log(config.foo); // bar
Here, you will notice that once required, the JSON file is transformed into a JavaScript object implicitly. Other languages will have you read the file and perhaps use a different mechanism to convert the content into a data structure such as a map, a dictionary, and so on.
For local files, the extension is optional, but should there be a conflict, it might be necessary to specify the extension. If you have both a sample.js and a sample.json file in the same folder, the .js file will be picked by default; it would be prudent to specify the extension, for example const config = require(‘./config/sample.json’).
When you run npm install, without specifying the module to install, npm will install the list of packages specified (under dependencies and devDependencies in the package.json file in your project). If package.json does not exist, it will give an error indicating that no such file has been found.
Activity: Running Basic Node.js Code
Open the IDE and the Terminal to implement this solution and learn how to write a basic Node.js file and run it. Write a very basic mathematical library with handy mathematical functions using the following steps:
- Create your project directory (folder), where all the code for this will be kept. Inside this directory, create another directory named lesson-1, and inside it, create another directory called activity-a. All this can be done using the following command:
mkdir -p beginning-nodejs/lesson-1/activity-a
- Inside activity-a, create a file using the touch maths.js
- Inside this file, create the following functions:
- add: This takes any two numbers and returns the sum of both, for example, add(2, 5)returns 7
- sum: Unlike add, sum takes any number of numbers and returns their sum, for example, sum(10, 5, 6)returns 21
- After these functions, write the following code to act as tests for your code:
console.log(add(10, 6)); // 16 console.log(sum(10, 5, 6)); // 21
- Now, on the Terminal, change directory to lesson-1.
- To run the code, run the following command:
node activity-a/math.js
The 16 and 21 values should be printed out on the Terminal.
Activity: Using a Third-Party Package
This activity will build upon the, Running Basic Node.js activity. If the argument is a single array, sum up the numbers, and if it’s more than one array, first combine the arrays into one before summing up. Use the concat() function from lodash, which is a third-party package that you need to install.
Now create a new function, sumArray, which can sum up numbers from one or more arrays using the following steps:
- Inside Lesson-1, create another folder called activity-b.
- On the Terminal, change directory to activity-band run the following command:
npm init
- This will take you to an interactive prompt; just press Enter all the way, leaving the answers as suggested defaults. The aim here is to get a json file, which will help organize your installed packages.
- Since you’ll be using lodash, install it. Run the following command:
npm install lodash--save
Notice that you’re adding the –save option on your command so that the package installed can be tracked in package.json. When you open the package.json file created in step 3, you will see an added dependencies key with the details.
- Create a jsfile in the activity-b directory and copy the math.js code from Activity, Running Basic Node.js into this file.
- Now, add the sumArrayfunction right after the sum
- Start with requiring lodash, which you installed in step 4 since you’re going to use it in the sumArrayfunction:
const _ = require('lodash');
- The sumArrayfunction should call the sum function to reuse your code. Use the spread operator on the array. See the following code:
function sumArray() { let arr = arguments[0]; if (arguments.length > 1) { arr = _.concat(...arguments); } // reusing the sum function // using the spread operator (...) since // sum takes an argument of numbers return sum(...arr); }
- At the end of the file, export the three functions, add, sum, and sumArraywith exports.
- In the same activity-bfolder, create a file, js.
- In jsfile, require ./math.js and go ahead to use sumArray:
// testing console.log(math.sumArray([10, 5, 6])); // 21 console.log(math.sumArray([10, 5], [5, 6], [1, 3])) // 30
- Run the following code on the Terminal:
node index.js
You should see 21 and 30 printed out.
If you found this article interesting, you can explore Anthony Nandaa’s Beginning API Development with Node.js to learn everything you need to get up and running with cutting-edge API development using JavaScript and Node.js. Beginning API Development with Node.js begins with the basics of Node.js in the context of backend development and quickly leads you through the creation of an example client that pairs up with a fully authenticated API implementation.