From b0adaff67e492ab9ac583059f5e2dba54de0973b Mon Sep 17 00:00:00 2001 From: isaacs Date: Wed, 13 Oct 2010 17:15:56 -0700 Subject: [PATCH] require looks in node_modules folders for modules starting with the __dirname and moving up. This makes it much easier to localize dependencies to a particular program. --- doc/api.markdown | 14 +++++++++++--- src/node.js | 18 ++++++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/doc/api.markdown b/doc/api.markdown index 3dc1e63e88..9f8d76546c 100644 --- a/doc/api.markdown +++ b/doc/api.markdown @@ -446,13 +446,12 @@ but rather than loading the module, just return the resolved filename. ### require.paths -An array of search paths for `require()`. This array can be modified to add custom paths. +An array of search paths for `require()`. This array can be modified to add +custom paths. Example: add a new path to the beginning of the search list require.paths.unshift('/usr/local/node'); - console.log(require.paths); - // /usr/local/node,/Users/mjr/.node_libraries ### __filename @@ -3259,6 +3258,15 @@ a directory. `require.paths` can be modified at runtime by simply unshifting new paths onto it, or at startup with the `NODE_PATH` environmental variable (which should be a list of paths, colon separated). +Additionally node will search for directories called `node_modules` starting +at the current directory (of the module calling `require`) and upwards +towards the root of the package tree. +This feature makes it easy to have different module versions for different +environments. Imagine the situation where you have a devopment environment +and a production environment each with a different version of the `foo` +module: `projects/x/development/node_modules/foo` and +`projects/x/production/node_modules/foo`. + The second time `require('foo')` is called, it is not loaded again from disk. It looks in the `require.cache` object to see if it has been loaded diff --git a/src/node.js b/src/node.js index 261a3590ad..0fe36fce38 100644 --- a/src/node.js +++ b/src/node.js @@ -170,7 +170,7 @@ var module = (function () { } function findModulePath (request, paths) { - var nextLoc = traverser(request, request.charAt(0) === '/' ? [''] : paths); + var nextLoc = traverser(request, paths); var fs = requireNative('fs'); @@ -182,15 +182,29 @@ var module = (function () { return false; } + function modulePathWalk (parent) { + if (parent._modulePaths) return parent._modulePaths; + var p = parent.filename.split("/"); + var mp = []; + while (undefined !== p.pop()) { + mp.push(p.join("/")+"/node_modules"); + } + return parent._modulePaths = mp; + } // sync - no i/o performed function resolveModuleLookupPaths (request, parent) { if (natives[request]) return [request, []]; + if (request.charAt(0) === '/') { + return [request, ['']]; + } + var start = request.substring(0, 2); if (start !== "./" && start !== "..") { - return [request, modulePaths.concat(defaultPaths)]; + var paths = modulePaths.concat(modulePathWalk(parent)).concat(defaultPaths); + return [request, paths]; } // Is the parent an index module?