Skip to content

Commit

Permalink
[Breaking] bring resolve into line with require.resolve, which do…
Browse files Browse the repository at this point in the history
…es not respect trailing slashes on non-directories.
  • Loading branch information
ljharb committed Mar 13, 2017
1 parent 1f86ce1 commit b1fb413
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 12 deletions.
51 changes: 40 additions & 11 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,51 @@ module.exports = function resolve(x, options, callback) {

opts.paths = opts.paths || [];

function isFileWithExtensions(file, cb, extensionIndex) {
var newExtensionIndex = 0;
var filename = file;
if (typeof extensionIndex === 'number') {
if (extensionIndex >= extensions.length) {
return cb(null, false);
}

newExtensionIndex = extensionIndex + 1;
filename = file + extensions[extensionIndex];
}

isFile(filename, function (err, filenameIsFile) {
if (err) { return cb(err); }
if (filenameIsFile) {
return cb(null, filenameIsFile);
}
isFileWithExtensions(file, cb, newExtensionIndex);
});
}

if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
var res = path.resolve(basedir, x);
var res = path.normalize(path.join(basedir, x));
if (x === '..' || x.slice(-1) === '/') res += '/';
if (/\/$/.test(x) && res === basedir) {
loadAsDirectory(res, opts.package, onfile);
} else loadAsFile(res, opts.package, onfile);
} 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 {
var moduleError = new Error("Cannot find module '" + x + "' from '" + basedir + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
} else {
isFileWithExtensions(res, function (err, resIsFile) {
if (err) { return onfile(err); }
if (resIsFile) { return loadAsFile(res, opts.package, onfile); }
return loadAsDirectory(res, opts.package, onfile);
});
}
});
} else {
loadNodeModules(x, basedir, function (err, n, pkg) {
if (err) cb(err);
else if (core[x]) return cb(null, x);
else if (n) cb(null, n, pkg);
else {
var moduleError = new Error("Cannot find module '" + x + "' from '" + basedir + "'");
moduleError.code = 'MODULE_NOT_FOUND';
cb(moduleError);
}
});
}

function onfile(err, m, pkg) {
if (err) cb(err);
Expand Down
2 changes: 1 addition & 1 deletion lib/sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = function (x, options) {
opts.paths = opts.paths || [];

if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
var res = path.resolve(basedir, x);
var res = path.normalize(path.join(basedir, x));
if (x === '..' || x.slice(-1) === '/') res += '/';
var m = loadAsFileSync(res) || loadAsDirectorySync(res);
if (m) return m;
Expand Down
17 changes: 17 additions & 0 deletions test/resolver.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,23 @@ test('async: #121 - treating an existing file as a dir when no basedir', functio
});
});

t.test('with a trailing slash', function (st) {
st.plan(4);

resolve('./' + testFile + '/', function (err, res, pkg) {
st.ok(err, 'there is an error');
st.notOk(res, 'no result');

st.equal(err && err.code, 'MODULE_NOT_FOUND', 'error code matches require.resolve');
st.equal(
err && err.message,
'Cannot find module \'./' + testFile + '/\' from \'' + __dirname + '\'',
'can not find nonexistent module'
);
st.end();
});
});

t.test('with a fake directory', function (st) {
st.plan(4);

Expand Down
19 changes: 19 additions & 0 deletions test/resolver_sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,25 @@ test('sync: #121 - treating an existing file as a dir when no basedir', function
st.end();
});

t.test('with a trailing slash', function (st) {
function run() { return resolve.sync('./' + testFile + '/'); }

st.throws(run, 'throws an error');

try {
run();
} catch (e) {
st.equal(e.code, 'MODULE_NOT_FOUND', 'error code matches require.resolve');
st.equal(
e.message,
'Cannot find module \'./' + testFile + '/\' from \'' + __dirname + '\'',
'can not find nonexistent module'
);
}

st.end();
});

t.test('with a fake directory', function (st) {
function run() { return resolve.sync('./' + testFile + '/blah'); }

Expand Down

0 comments on commit b1fb413

Please sign in to comment.