diff --git a/index.js b/index.js index 0ceba0b..983073b 100644 --- a/index.js +++ b/index.js @@ -14,7 +14,6 @@ * * > loadModule('something.js', { paths: [ '.', '~/my-modules' ] }) */ -module.exports = loadModule /** * @alias module:load-module @@ -35,19 +34,77 @@ function loadModule (request, options) { if (paths && paths.length) { module.paths = module.paths.concat(paths) } - let output + let output = null if (prefix) { - /* Try first with the prefix then without */ try { - output = require(require.resolve(`${options.prefix}${request}`, { paths })) + output = loadModule(`${prefix}${request}`, { paths }) } catch (err) { - output = require(require.resolve(request, { paths })) + if (err.code === 'MODULE_NOT_FOUND') { + output = loadModule(request, { paths }) + } else { + throw err + } } } else { - output = require(require.resolve(request, { paths })) + output = loadAsLocalPath(request, { paths }) + if (output === null) { + output = loadAsRegularRequire(request, { paths }) + } + if (output === null) { + output = tryEachPath(request, { paths }) + } } module.paths = origModulePaths + + if (output === null) { + const err = new Error('Cannot find ' + request) + err.code = 'MODULE_NOT_FOUND' + throw err + } else { + return output + } +} + +function loadAsLocalPath (request, options) { + const path = require('path') + let output + try { + output = require(path.resolve(request), options) + } catch (err) { + if (err.code === 'MODULE_NOT_FOUND') { + output = null + } else { + throw err + } + } return output } + +function loadAsRegularRequire (request, options) { + let output + try { + output = require(require.resolve(request, options)) + } catch (err) { + if (err.code === 'MODULE_NOT_FOUND') { + output = null + } else { + throw err + } + } + return output +} + +function tryEachPath (request, options) { + const path = require('path') + let output = null + for (const p of options.paths || []) { + const fullPath = path.resolve(p, request) + output = loadAsRegularRequire(fullPath) + if (output !== null) break + } + return output +} + +module.exports = loadModule diff --git a/test/broken.js b/test/exceptions.js similarity index 92% rename from test/broken.js rename to test/exceptions.js index 96c9020..dd63c86 100644 --- a/test/broken.js +++ b/test/exceptions.js @@ -3,7 +3,7 @@ const loadModule = require('../') const a = require('assert') const path = require('path') -const tom = module.exports = new Tom('broken') +const tom = module.exports = new Tom('exceptions') tom.test('broken module', function () { a.throws( diff --git a/test/simple.js b/test/simple.js index 9f20807..3010454 100644 --- a/test/simple.js +++ b/test/simple.js @@ -5,31 +5,49 @@ const path = require('path') const tom = module.exports = new Tom('simple') -tom.test('relative path to file', function () { +const noOptions = tom.test('no options') + +noOptions.test('module name', function () { + const result = loadModule('array-back') + a.strictEqual(result.name, 'arrayify') +}) + +const relative = tom.test('relative path') + +relative.test('to file', function () { const modulePath = './test/fixture/loadModule/some-module/lib/some-module.js' const result = loadModule(modulePath) a.strictEqual(result.name, 'someModule') }) -tom.test('absolute path to file', function () { - const modulePath = path.resolve(__dirname, './fixture/loadModule/some-module/lib/some-module.js') +relative.test('to module dir', function () { + const modulePath = './test/fixture/loadModule/some-module' const result = loadModule(modulePath) a.strictEqual(result.name, 'someModule') }) -tom.test('relative path to module dir', function () { - const modulePath = './test/fixture/loadModule/some-module' +relative.test('to file, no ./', function () { + const modulePath = 'test/fixture/loadModule/some-module/lib/some-module.js' const result = loadModule(modulePath) a.strictEqual(result.name, 'someModule') }) -tom.test('absolute path to module dir', function () { - const modulePath = path.resolve(__dirname, 'fixture/loadModule/some-module') +relative.test('to module dir, no ./', function () { + const modulePath = 'test/fixture/loadModule/some-module' const result = loadModule(modulePath) a.strictEqual(result.name, 'someModule') }) -tom.test('module name', function () { - const result = loadModule('array-back') - a.strictEqual(result.name, 'arrayify') +const absolute = tom.test('absolute path') + +absolute.test('to file', function () { + const modulePath = path.resolve(__dirname, './fixture/loadModule/some-module/lib/some-module.js') + const result = loadModule(modulePath) + a.strictEqual(result.name, 'someModule') +}) + +absolute.test('to module dir', function () { + const modulePath = path.resolve(__dirname, 'fixture/loadModule/some-module') + const result = loadModule(modulePath) + a.strictEqual(result.name, 'someModule') })