diff --git a/lib/require-hook.js b/lib/require-hook.js index 56ab96c..9acc3f5 100644 --- a/lib/require-hook.js +++ b/lib/require-hook.js @@ -18,6 +18,79 @@ module.exports = function requireHook (opts) { var hasSetMain = false; var currentWrapFile = null; + function resolveSymlink (filePath) { + while (fs.existsSync(filePath) && fs.lstatSync(filePath).isSymbolicLink()) { + filePath = fs.readlinkSync(filePath); + } + return filePath; + } + + // Searches each parent directory for a 'package.json' + function resolvePackage (pkgRoot) { + while (pkgRoot !== path.sep) { + pkgPath = path.join(pkgRoot, 'package.json'); + if (fs.existsSync(pkgPath)) { + return resolveSymlink(pkgRoot); + } + pkgRoot = path.dirname(pkgRoot); + } + return null; + } + + // Searches each 'node_modules' directory + // for a module (including the global root) + function resolveModule (request, parent) { + var pkgRoot = resolvePackage( + parent.id === '.' ? + process.cwd() : + path.dirname(parent.id) + ); + if (pkgRoot) { + var depName = request.split(path.sep)[0]; + var depPath = resolveSymlink( + path.join(pkgRoot, 'node_modules', depName) + ); + if (fs.existsSync(depPath)) { + return path.join( + depPath, + path.relative(depName, request) + ); + } + + // + // Search each directory in $NODE_PATH + // + var nodePaths = process.env.NODE_PATH.split(':'); + for (var i = 0; i < nodePaths.length; i++) { + pkgRoot = nodePaths[i]; + if (fs.existsSync(pkgRoot) && fs.statSync(pkgRoot).isDirectory()) { + depPath = resolveSymlink( + path.join(pkgRoot, depName) + ); + if (fs.existsSync(depPath)) { + return path.join( + depPath, + path.relative(depName, request) + ); + } + } + } + } + return request; + } + + var loadModule = Module._load; + Module._load = function(request, parent, isMain) { + if (request[0] === '.') { + if (parent.id === '.') { + request = path.resolve(process.cwd(), request); + } + } else if (request[0] !== path.sep) { + request = resolveModule(request, parent); + } + return loadModule(request, parent, isMain); + }; + require.extensions['.js'] = function devtoolCompileModule (module, file) { // set the main module so that Node.js scripts run correctly if (!hasSetMain && entry && file === entry) {