diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 10db311e88..8f94f6b248 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -202,7 +202,7 @@ code. ### DEP0019: require('.') resolved outside directory -Type: End-of-Life +Type: Runtime In certain cases, `require('.')` may resolve outside the package directory. This behavior is deprecated and will be removed in a future major Node.js diff --git a/lib/module.js b/lib/module.js index 921a57a814..e418a1a3e0 100644 --- a/lib/module.js +++ b/lib/module.js @@ -176,6 +176,7 @@ function tryExtensions(p, exts, isMain) { return false; } +var warned = false; Module._findPath = function(request, paths, isMain) { if (path.isAbsolute(request)) { paths = ['']; @@ -232,6 +233,18 @@ Module._findPath = function(request, paths, isMain) { } if (filename) { + // Warn once if '.' resolved outside the module dir + if (request === '.' && i > 0) { + if (!warned) { + warned = true; + process.emitWarning( + 'warning: require(\'.\') resolved outside the package ' + + 'directory. This functionality is deprecated and will be removed ' + + 'soon.', + 'DeprecationWarning', 'DEP0019'); + } + } + Module._pathCache[cacheKey] = filename; return filename; } @@ -334,7 +347,8 @@ Module._resolveLookupPaths = function(request, parent, newReturn) { } // Check for relative path - if (request.charCodeAt(0) !== 46/*.*/ && + if (request.length < 2 || + request.charCodeAt(0) !== 46/*.*/ || (request.charCodeAt(1) !== 46/*.*/ && request.charCodeAt(1) !== 47/*/*/)) { var paths = modulePaths; @@ -345,6 +359,16 @@ Module._resolveLookupPaths = function(request, parent, newReturn) { paths = parent.paths.concat(paths); } + // Maintain backwards compat with certain broken uses of require('.') + // by putting the module's directory in front of the lookup paths. + if (request === '.') { + if (parent && parent.filename) { + paths.unshift(path.dirname(parent.filename)); + } else { + paths.unshift(path.resolve(request)); + } + } + debug('looking for %j in %j', request, paths); return (newReturn ? (paths.length > 0 ? paths : null) : [request, paths]); } diff --git a/test/parallel/test-require-dot.js b/test/parallel/test-require-dot.js index 2e8a5c79f6..e2202efec1 100644 --- a/test/parallel/test-require-dot.js +++ b/test/parallel/test-require-dot.js @@ -10,7 +10,9 @@ const b = require(fixtures.path('module-require', 'relative', 'dot-slash.js')); assert.strictEqual(a.value, 42); assert.strictEqual(a, b, 'require(".") should resolve like require("./")'); -// require('.') should not lookup in NODE_PATH process.env.NODE_PATH = fixtures.path('module-require', 'relative'); m._initPaths(); -assert.throws(() => { require('.'); }, Error, "Cannot find module '.'"); + +const c = require('.'); + +assert.strictEqual(c.value, 42, 'require(".") should honor NODE_PATH');