require looks in node_modules folders
authorisaacs <i@izs.me>
Thu, 14 Oct 2010 00:15:56 +0000 (17:15 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Wed, 20 Oct 2010 22:45:47 +0000 (15:45 -0700)
for modules starting with the __dirname and moving up.

This makes it much easier to localize dependencies to a particular program.

doc/api.markdown
src/node.js

index 3dc1e63..9f8d765 100644 (file)
@@ -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
index 261a359..0fe36fc 100644 (file)
@@ -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?