From fb0cbebf02cb2b00383cc044129c1ac852c513af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ma=C3=ABl=20Nison?= Date: Thu, 2 Jan 2020 11:18:57 +0100 Subject: [PATCH] utils: Uses createRequireFromPath to resolve loaders --- .../eslint-import-resolver-foo/index.js | 1 + tests/src/core/resolve.js | 8 +++++++ tests/src/rules/no-unresolved.js | 8 +++---- utils/CHANGELOG.md | 6 ++++- utils/resolve.js | 24 +++++++++++++++---- 5 files changed, 38 insertions(+), 9 deletions(-) create mode 120000 tests/files/node_modules/eslint-import-resolver-foo/index.js diff --git a/tests/files/node_modules/eslint-import-resolver-foo/index.js b/tests/files/node_modules/eslint-import-resolver-foo/index.js new file mode 120000 index 000000000..d194dba0d --- /dev/null +++ b/tests/files/node_modules/eslint-import-resolver-foo/index.js @@ -0,0 +1 @@ +../../foo-bar-resolver-v2.js \ No newline at end of file diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 5d5bd3a20..3bf46cd1a 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -94,6 +94,14 @@ describe('resolve', function () { )).to.equal(utils.testFilePath('./bar.jsx')) }) + it('finds resolvers from the source files rather than eslint-module-utils', function () { + const testContext = utils.testContext({ 'import/resolver': { 'foo': {} } }) + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }), + )).to.equal(utils.testFilePath('./bar.jsx')) + }) + it('reports invalid import/resolver config', function () { const testContext = utils.testContext({ 'import/resolver': 123.456 }) const testContextReports = [] diff --git a/tests/src/rules/no-unresolved.js b/tests/src/rules/no-unresolved.js index cae6e8468..cc3aca884 100644 --- a/tests/src/rules/no-unresolved.js +++ b/tests/src/rules/no-unresolved.js @@ -343,9 +343,9 @@ ruleTester.run('no-unresolved unknown resolver', rule, { // logs resolver load error test({ code: 'import "./malformed.js"', - settings: { 'import/resolver': 'foo' }, + settings: { 'import/resolver': 'doesnt-exist' }, errors: [ - `Resolve error: unable to load resolver "foo".`, + `Resolve error: unable to load resolver "doesnt-exist".`, `Unable to resolve path to module './malformed.js'.`, ], }), @@ -353,9 +353,9 @@ ruleTester.run('no-unresolved unknown resolver', rule, { // only logs resolver message once test({ code: 'import "./malformed.js"; import "./fake.js"', - settings: { 'import/resolver': 'foo' }, + settings: { 'import/resolver': 'doesnt-exist' }, errors: [ - `Resolve error: unable to load resolver "foo".`, + `Resolve error: unable to load resolver "doesnt-exist".`, `Unable to resolve path to module './malformed.js'.`, `Unable to resolve path to module './fake.js'.`, ], diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index 8165447b7..6a7fe6764 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -5,6 +5,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +### Fixed +- Uses createRequireFromPath to resolve loaders ([#1591], thanks [@arcanis]) + ## v2.5.0 - 2019-12-07 ### Added @@ -59,7 +62,7 @@ Yanked due to critical issue with cache key resulting from #839. - `unambiguous.test()` regex is now properly in multiline mode - +[#1591]: https://github.com/benmosher/eslint-plugin-import/pull/1591 [#1551]: https://github.com/benmosher/eslint-plugin-import/pull/1551 [#1435]: https://github.com/benmosher/eslint-plugin-import/pull/1435 [#1409]: https://github.com/benmosher/eslint-plugin-import/pull/1409 @@ -77,3 +80,4 @@ Yanked due to critical issue with cache key resulting from #839. [@christophercurrie]: https://github.com/christophercurrie [@brettz9]: https://github.com/brettz9 [@JounQin]: https://github.com/JounQin +[@arcanis]: https://github.com/arcanis diff --git a/utils/resolve.js b/utils/resolve.js index 92c8f3500..945ba4b6f 100644 --- a/utils/resolve.js +++ b/utils/resolve.js @@ -4,6 +4,7 @@ exports.__esModule = true const pkgDir = require('pkg-dir') const fs = require('fs') +const Module = require('module') const path = require('path') const hashObject = require('./hash').hashObject @@ -14,11 +15,26 @@ exports.CASE_SENSITIVE_FS = CASE_SENSITIVE_FS const fileExistsCache = new ModuleCache() -function tryRequire(target) { +// Polyfill Node's `Module.createRequireFromPath` if not present (added in Node v10.12.0) +const createRequireFromPath = Module.createRequireFromPath || function (filename) { + const mod = new Module(filename, null) + mod.filename = filename + mod.paths = Module._nodeModulePaths(path.dirname(filename)) + + mod._compile(`module.exports = require;`, filename) + + return mod.exports +} + +function tryRequire(target, sourceFile) { let resolved try { // Check if the target exists - resolved = require.resolve(target) + if (sourceFile != null) { + resolved = createRequireFromPath(sourceFile).resolve(target) + } else { + resolved = require.resolve(target) + } } catch(e) { // If the target does not exist then just return undefined return undefined @@ -154,8 +170,8 @@ function getBaseDir(sourceFile) { } function requireResolver(name, sourceFile) { // Try to resolve package with conventional name - let resolver = tryRequire(`eslint-import-resolver-${name}`) || - tryRequire(name) || + let resolver = tryRequire(`eslint-import-resolver-${name}`, sourceFile) || + tryRequire(name, sourceFile) || tryRequire(path.resolve(getBaseDir(sourceFile), name)) if (!resolver) {