Modules in Node.js - JavaScript Application Design: A Build First Approach (2015)

JavaScript Application Design: A Build First Approach (2015)

Appendix A. Modules in Node.js

This appendix covers things you need to know about modules and Node.js to use both effectively in your Grunt builds. Node.js is a platform built on top of the V8 JavaScript engine, the same engine that makes JavaScript in Google Chrome a reality. Grunt, the build tool you use in this book, runs on Node. Node is single threaded, as all JavaScript is.

Node comes with a nice little companion command-line interface (CLI) utility called npm, which is used to fetch and install packages from the node-packaged modules registry. Throughout the book, you’ll learn how to use the npm tool as needed. Let’s install Node.js first, since npm comes bundled with it!

A.1. Installing Node.js

You have a few options for installing Node. If you’re the point-and-click type, then you might want to head over to their website, http://nodejs.org, and click on the big green Install button. Once the binaries are downloaded, unpack them if needed, and then double-click to install them. That’s it.

If you prefer to install things in your terminal, consider nvm, a user-created Node version manager. To install nvm, you can type the following line into your terminal:

curl https://raw.github.com/creationix/nvm/master/install.sh | bash

Once nvm is installed, reopen your terminal window to get access to the nvm CLI. If you have any issues installing nvm, refer to their public repository at https://github.com/creationix/nvm. Once you have nvm you can install a version of Node, as shown in the following code:

nvm install 0.10

nvm alias default stable

The first command installs the latest stable version of Node in the 0.10.x branch. The second command makes it so that any terminal window you open from now on will have access to the Node version you installed.

Great, now you have Node! Time for you to learn more about its module system, which is based on the CommonJS module’s spec.

A.2. The module system

Node applications have an entry point that’s specified when executing a node process. For example, if you run node app.js, your Node process will use app.js as the entry point. To load other pieces of code, you have to use the require function. This function takes a path and loads the module found in that location. The path passed to require can be

· A path relative to the script you require from, starting with '.'. For example, if you do require('./main.js'), you’ll load a file that’s in the same directory as the requiring script. We can also use .. to get a script in a parent directory.

· A path to a directory. In these cases, require will look for a file named index.js in the provided directory and give you that.

· An absolute path. This one is rarely used, but you could provide an absolute file path, as shown in the following code:

require('/Users/nico/dev/buildfirst/main.js')

· The name of a package. Packages can be required by just providing their name; for example, to get the async package, you should use require('async'). Most of the time, this is effectively the same as doing require('./node_modules/async').

A.3. Exporting functionality

Requiring modules wouldn’t be useful if you couldn’t interact with them. Modules can export functionality, effectively their API, by assigning to module.exports. As an example, consider the following module:

var mine = 'gold';

module.exports = function (pure) {

return pure + mine;

};

If you fetched this module using var thing = require('./thing.js'), then thing would be assigned whatever module.exports ended up becoming inside thing.js. It is interesting to note that, unlike the browser model, where there are implicit globals assigned to window, the CommonJS module system keeps variables you declare in a module private unless you explicitly make them public by assigning to module .exports. Node has a global object you can assign to, which is called global, but using it is discouraged because that would break the modularity principle.

A.4. Regarding packages

Dependencies are kept in a package.json file, which is used by npm to figure out what packages you need to execute an application. When installing a package, you can provide a --save flag to have npm automatically persist that dependency to the package.json manifest, so you don’t have to do that by hand. Dependencies in package.json get installed whenever you run npm install without any arguments.

Local dependencies are installed to a node_modules directory, which should be ignored in version control. In the case of Git, you can add a line containing node_modules to a file named .gitignore, and Git will know not to revision those files.

That’s all you need to know about Node to use it effectively in your Grunt builds.