diff --git a/.eslintrc b/.eslintrc index 4f5155ee..d7485182 100644 --- a/.eslintrc +++ b/.eslintrc @@ -27,5 +27,13 @@ "object-curly-newline": 0, "operator-linebreak": [2, "before"], "sort-keys": 0, - } + }, + "overrides": [ + { + "files": "test/resolver/nested_symlinks/mylib/*.js", + "rules": { + "no-throw-literal": 0, + }, + }, + ], } diff --git a/lib/async.js b/lib/async.js index 310ea698..a46e3f18 100644 --- a/lib/async.js +++ b/lib/async.js @@ -99,8 +99,15 @@ module.exports = function resolve(x, options, callback) { } else loadNodeModules(x, basedir, function (err, n, pkg) { if (err) cb(err); else if (core[x]) return cb(null, x); - else if (n) return cb(null, n, pkg); - else { + else if (n) { + return maybeUnwrapSymlink(n, opts, function (err, realN) { + if (err) { + cb(err); + } else { + cb(null, realN, pkg); + } + }); + } else { var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); moduleError.code = 'MODULE_NOT_FOUND'; cb(moduleError); @@ -113,8 +120,15 @@ module.exports = function resolve(x, options, callback) { else if (m) cb(null, m, pkg); else loadAsDirectory(res, function (err, d, pkg) { if (err) cb(err); - else if (d) cb(null, d, pkg); - else { + else if (d) { + maybeUnwrapSymlink(d, opts, function (err, realD) { + if (err) { + cb(err); + } else { + cb(null, realD, pkg); + } + }); + } else { var moduleError = new Error("Cannot find module '" + x + "' from '" + parent + "'"); moduleError.code = 'MODULE_NOT_FOUND'; cb(moduleError); diff --git a/lib/sync.js b/lib/sync.js index a025df6e..3af96a72 100644 --- a/lib/sync.js +++ b/lib/sync.js @@ -67,12 +67,12 @@ module.exports = function (x, options) { var res = path.resolve(absoluteStart, x); if (x === '..' || x.slice(-1) === '/') res += '/'; var m = loadAsFileSync(res) || loadAsDirectorySync(res); - if (m) return m; + if (m) return maybeUnwrapSymlink(m, opts); } else if (core[x]) { return x; } else { var n = loadNodeModulesSync(x, absoluteStart); - if (n) return n; + if (n) return maybeUnwrapSymlink(n, opts); } if (core[x]) return x; diff --git a/package.json b/package.json index 9fbd9e2f..19b634c8 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "scripts": { "prepublish": "safe-publish-latest", "lint": "eslint .", + "pretests-only": "cd ./test/resolver/nested_symlinks && node mylib/sync && node mylib/async", "tests-only": "tape test/*.js", "pretest": "npm run lint", "test": "npm run --silent tests-only", diff --git a/test/resolver/nested_symlinks/common/node_modules/buffer/index.js b/test/resolver/nested_symlinks/common/node_modules/buffer/index.js new file mode 100644 index 00000000..66c989cb --- /dev/null +++ b/test/resolver/nested_symlinks/common/node_modules/buffer/index.js @@ -0,0 +1 @@ +module.exports = Buffer; diff --git a/test/resolver/nested_symlinks/common/node_modules/buffer/package.json b/test/resolver/nested_symlinks/common/node_modules/buffer/package.json new file mode 100644 index 00000000..79ff3830 --- /dev/null +++ b/test/resolver/nested_symlinks/common/node_modules/buffer/package.json @@ -0,0 +1,7 @@ +{ + "description": "fake buffer shim", + "main": "index.js", + "name": "buffer", + "version": "0.0.0", + "private": true +} diff --git a/test/resolver/nested_symlinks/mylib/async.js b/test/resolver/nested_symlinks/mylib/async.js new file mode 100644 index 00000000..9b4846a8 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/async.js @@ -0,0 +1,26 @@ +var a = require.resolve('buffer/').replace(process.cwd(), '$CWD'); +var b; +var c; + +var test = function test() { + console.log(a, ': require.resolve, preserveSymlinks ' + (process.execArgv.indexOf('preserve-symlinks') > -1 ? 'true' : 'false')); + console.log(b, ': preserveSymlinks true'); + console.log(c, ': preserveSymlinks false'); + + if (a !== b && a !== c) { + throw 'async: no match'; + } + console.log('async: success! a matched either b or c\n'); +}; + +require('resolve')('buffer/', { preserveSymlinks: true }, function (err, result) { + if (err) { throw err; } + b = result.replace(process.cwd(), '$CWD'); + if (b && c) { test(); } +}); +require('resolve')('buffer/', { preserveSymlinks: false }, function (err, result) { + if (err) { throw err; } + c = result.replace(process.cwd(), '$CWD'); + if (b && c) { test(); } +}); + diff --git a/test/resolver/nested_symlinks/mylib/node_modules/buffer b/test/resolver/nested_symlinks/mylib/node_modules/buffer new file mode 120000 index 00000000..b46997bb --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/node_modules/buffer @@ -0,0 +1 @@ +../../common/node_modules/buffer \ No newline at end of file diff --git a/test/resolver/nested_symlinks/mylib/node_modules/resolve b/test/resolver/nested_symlinks/mylib/node_modules/resolve new file mode 120000 index 00000000..59307833 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/node_modules/resolve @@ -0,0 +1 @@ +../../../../.. \ No newline at end of file diff --git a/test/resolver/nested_symlinks/mylib/package.json b/test/resolver/nested_symlinks/mylib/package.json new file mode 100644 index 00000000..acfe9e95 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/package.json @@ -0,0 +1,15 @@ +{ + "name": "mylib", + "version": "0.0.0", + "description": "", + "private": true, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "buffer": "*" + } +} diff --git a/test/resolver/nested_symlinks/mylib/sync.js b/test/resolver/nested_symlinks/mylib/sync.js new file mode 100644 index 00000000..3283efc2 --- /dev/null +++ b/test/resolver/nested_symlinks/mylib/sync.js @@ -0,0 +1,12 @@ +var a = require.resolve('buffer/').replace(process.cwd(), '$CWD'); +var b = require('resolve').sync('buffer/', { preserveSymlinks: true }).replace(process.cwd(), '$CWD'); +var c = require('resolve').sync('buffer/', { preserveSymlinks: false }).replace(process.cwd(), '$CWD'); + +console.log(a, ': require.resolve, preserveSymlinks ' + (process.execArgv.indexOf('preserve-symlinks') > -1 ? 'true' : 'false')); +console.log(b, ': preserveSymlinks true'); +console.log(c, ': preserveSymlinks false'); + +if (a !== b && a !== c) { + throw 'sync: no match'; +} +console.log('sync: success! a matched either b or c\n');