-
-
Notifications
You must be signed in to change notification settings - Fork 34.3k
module: resolve _-prefixed dependencies to real path #6460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
6564aae
37b7b5e
0ef4591
ca804f5
994f7ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -103,20 +103,30 @@ function tryPackage(requestPath, exts, isMain) { | |
| if (!pkg) return false; | ||
|
|
||
| var filename = path.resolve(requestPath, pkg); | ||
| return readPackagePath(filename, exts, isMain); | ||
| } | ||
|
|
||
| function readPackagePath(filename, exts, isMain) { | ||
| return tryFile(filename, isMain) || | ||
| tryExtensions(filename, exts, isMain) || | ||
| tryExtensions(path.resolve(filename, 'index'), exts, isMain); | ||
| } | ||
|
|
||
| function readFilePath(requestPath, isMain) { | ||
| if (isMain) { | ||
| return fs.realpathSync(requestPath); | ||
| } | ||
| return path.resolve(requestPath); | ||
| } | ||
|
|
||
| // check if the file exists and is not a directory | ||
| // resolve to the absolute realpath if running main module, | ||
| // otherwise resolve to absolute while keeping symlinks intact. | ||
| function tryFile(requestPath, isMain) { | ||
| const rc = stat(requestPath); | ||
| if (isMain) { | ||
| return rc === 0 && fs.realpathSync(requestPath); | ||
| if (rc === 0) { | ||
| return readFilePath(requestPath, isMain); | ||
| } | ||
| return rc === 0 && path.resolve(requestPath); | ||
| } | ||
|
|
||
| // given a path check a the file exists with any of the set extensions | ||
|
|
@@ -131,6 +141,34 @@ function tryExtensions(p, exts, isMain) { | |
| return false; | ||
| } | ||
|
|
||
| function tryFindPath(basePath, exts, isMain, isAbsolute) { | ||
| var filename; | ||
|
|
||
| if (isAbsolute) { | ||
| const rc = stat(basePath); | ||
| if (rc === 0) { // File. | ||
| filename = readFilePath(basePath, isMain); | ||
| } else if (rc === 1) { // Directory. | ||
| filename = tryPackage(basePath, exts, isMain); | ||
| } | ||
|
|
||
| if (!filename) { | ||
| filename = tryExtensions(basePath, exts, isMain); | ||
| } | ||
| } | ||
|
|
||
| if (!filename) { | ||
| filename = tryPackage(basePath, exts, isMain); | ||
| } | ||
|
|
||
| if (!filename) { | ||
| // try it with each of the extensions at "index" | ||
| filename = tryExtensions(path.resolve(basePath, 'index'), exts, isMain); | ||
| } | ||
|
|
||
| return filename; | ||
| } | ||
|
|
||
| var warned = false; | ||
| Module._findPath = function(request, paths, isMain) { | ||
| if (path.isAbsolute(request)) { | ||
|
|
@@ -144,52 +182,24 @@ Module._findPath = function(request, paths, isMain) { | |
| return Module._pathCache[cacheKey]; | ||
| } | ||
|
|
||
| var exts; | ||
| const exts = Object.keys(Module._extensions); | ||
| const trailingSlash = request.length > 0 && | ||
| request.charCodeAt(request.length - 1) === 47/*/*/; | ||
| const isAbsolute = !trailingSlash; | ||
|
|
||
| // For each path | ||
| for (var i = 0; i < paths.length; i++) { | ||
| // Don't search further if path doesn't exist | ||
| const curPath = paths[i]; | ||
| if (curPath && stat(curPath) < 1) continue; | ||
| var basePath = path.resolve(curPath, request); | ||
| var filename; | ||
|
|
||
| if (!trailingSlash) { | ||
| const rc = stat(basePath); | ||
| if (rc === 0) { // File. | ||
| if (!isMain) { | ||
| filename = path.resolve(basePath); | ||
| } else { | ||
| filename = fs.realpathSync(basePath); | ||
| } | ||
| } else if (rc === 1) { // Directory. | ||
| if (exts === undefined) | ||
| exts = Object.keys(Module._extensions); | ||
| filename = tryPackage(basePath, exts, isMain); | ||
| } | ||
|
|
||
| if (!filename) { | ||
| // try it with each of the extensions | ||
| if (exts === undefined) | ||
| exts = Object.keys(Module._extensions); | ||
| filename = tryExtensions(basePath, exts, isMain); | ||
| } | ||
| } | ||
| // If _basePath is a symlink, use the real path rather than the path of the | ||
| // symlink as cache key. | ||
| const _basePath = path.resolve(curPath, '_' + request); | ||
| const basePath = path.resolve(curPath, request); | ||
|
||
|
|
||
| if (!filename) { | ||
| if (exts === undefined) | ||
| exts = Object.keys(Module._extensions); | ||
| filename = tryPackage(basePath, exts, isMain); | ||
| } | ||
|
|
||
| if (!filename) { | ||
| // try it with each of the extensions at "index" | ||
| if (exts === undefined) | ||
| exts = Object.keys(Module._extensions); | ||
| filename = tryExtensions(path.resolve(basePath, 'index'), exts, isMain); | ||
| } | ||
| const filename = tryFindPath(basePath, exts, isMain, isAbsolute) || | ||
|
||
| tryFindPath(_basePath, exts, true, isAbsolute); | ||
|
|
||
| if (filename) { | ||
| // Warn once if '.' resolved outside the module dir | ||
|
|
@@ -427,6 +437,7 @@ Module._resolveFilename = function(request, parent, isMain) { | |
| } | ||
|
|
||
| var resolvedModule = Module._resolveLookupPaths(request, parent); | ||
|
|
||
| var id = resolvedModule[0]; | ||
| var paths = resolvedModule[1]; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| exports.internalRequire = require; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| exports.dirname = __dirname; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| 'use strict'; | ||
| const common = require('../common'); | ||
| const assert = require('assert'); | ||
| const path = require('path'); | ||
| const fs = require('fs'); | ||
|
|
||
| const realModuleSymlinkPath = path.join(common.fixturesDir, | ||
| '/module-require-real-path/node_modules/_real-module'); | ||
|
|
||
| const linkModuleSymlinkPath = path.join(common.fixturesDir, | ||
| '/module-require-real-path/node_modules/_link-module'); | ||
|
|
||
| const localRealModulePath = path.join(common.fixturesDir, | ||
| '/module-require-real-path/real-module'); | ||
|
|
||
| // module-require-real-path exports its require function. That way we can test | ||
| // how modules get resolved **from** its. | ||
| const _require = require( | ||
| path.join(common.fixturesDir, '/module-require-real-path') | ||
| ).internalRequire; | ||
|
|
||
| process.on('exit', function() { | ||
| fs.unlinkSync(realModuleSymlinkPath); | ||
| fs.unlinkSync(linkModuleSymlinkPath); | ||
| }); | ||
|
|
||
| fs.symlinkSync('../real-module', realModuleSymlinkPath); | ||
| fs.symlinkSync('../real-module', linkModuleSymlinkPath); | ||
|
|
||
| assert.equal(_require('./real-module'), _require('real-module')); | ||
| assert.equal(_require('real-module').dirname, localRealModulePath); | ||
|
|
||
| // When required directly with the _-prefix, resolve to path of symlink. | ||
| assert.notEqual(_require('./real-module'), _require('_link-module')); | ||
| assert.equal(_require('_link-module').dirname, linkModuleSymlinkPath); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why was the lazy-loading of the extensions removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplified the control flow, since
tryFindPathwas split out in order to reduce redundancy (just likereadFilePath).More than happy to add it back in, but seemed like a very marginal cost to me.