var moduleA = require( "./module-a.js" ); var moduleB = require( "../../module-b.js" ); var moduleC = require( "/my-library/module-c.js" );
NOTE: The (.js) file extension is optional. Node.js will add it for you when attempting to load the file. It will also attempt to load the given module as a directory with an index file (index.js) or a package description (package.json).
Ok, so that stuff makes sense - relative file paths are something that I can wrap my head around. But what about when no file path is used? Where does Node.js look if you attempt to include a module by name alone:
var moduleA = require( "module-a" ); var moduleB = require( "module-b.js" );
This is where I really started to lose my sanity this morning! When you refer to a Node.js module by name, Node.js uses a complex searching algorithm to locate the requested source code.
First, Node.js looks to see if the given module is a core module - Node.js comes with many modules compiled directly into the executable binary (ex. http, fs, sys, events, path, etc.). These core modules will always take precedence in the loading algorithm.
var utils = require( "utils" );
... Node.js will perform a hierarchical directory search for "node_modules" and "utils" in the following ways:
If it still can't find the file in this directory-spidering manner, Node.js will then proceed to look at the directory paths outlined in the "require.paths" array. The paths values in this array default to the paths defined, in part, by the environmental variable, NODE_PATH; but, they can be updated programmatically within a Node.js application.
NOTE: From what I have read, programmatically updating the "require.paths" value is considered bad practice.
If I log my default require.paths value to the console, here is what I get:
I write all of this in an attempt to hammer this Node.js module search overview into my head. If you want to know more about Node.js's module search algorithm, check out the documentation on Modules. There, you can find a much more in-depth explanation of the search algorithm including module path caching and package descriptions.
Ok - now I can start to breathe a bit easier. I'm serious - I almost lost it a few times trying to get to the bottom of this.
Want to use code from this post? Check out the license.