diff --git a/package.json b/package.json index da167bc..99a2037 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ }, "peerDependencies": { "babel-core": "^6.0.0", - "babel-plugin-module-resolver": "^2.5.0" + "babel-plugin-module-resolver": ">3.0.0-beta" }, "scripts": { "lint": "eslint src test", diff --git a/src/index.js b/src/index.js index 14c2ad0..f96a40b 100644 --- a/src/index.js +++ b/src/index.js @@ -15,22 +15,38 @@ function getPlugins(file, target) { }); return result.plugins.filter((plugin) => { - const plug = OptionManager.memoisedPlugins.find(item => - item.plugin === plugin[0], - ); + const plug = OptionManager.memoisedPlugins.find(item => item.plugin === plugin[0]); return plug && plug.container === target; }); } catch (err) { - // This error should only occur if something goes wrong with babel's - // internals. Dump it to console so people know what's going on, - // elsewise the error will simply be squelched in the calling code. + // This error should only occur if something goes wrong with babel's + // internals. Dump it to console so people know what's going on, + // elsewise the error will simply be squelched in the calling code. console.error('[eslint-import-resolver-babel-module]', err); console.error('See: https://github.com/tleunen/eslint-import-resolver-babel-module/pull/34'); return []; } } +function stripWebpack(src) { + let source = src; + + // strip loaders + const finalBang = source.lastIndexOf('!'); + if (finalBang >= 0) { + source = source.slice(finalBang + 1); + } + + // strip resource query + const finalQuestionMark = source.lastIndexOf('?'); + if (finalQuestionMark >= 0) { + source = source.slice(0, finalQuestionMark); + } + + return source; +} + exports.interfaceVersion = 2; /** @@ -51,12 +67,15 @@ exports.resolve = (source, file, opts) => { try { const instances = getPlugins(file, targetPlugin); - const pluginOpts = instances.reduce((config, plugin) => ({ - cwd: plugin[1] && plugin[1].cwd ? plugin[1].cwd : config.cwd, - root: config.root.concat(plugin[1] && plugin[1].root ? plugin[1].root : []), - alias: Object.assign(config.alias, plugin[1] ? plugin[1].alias : {}), - extensions: plugin[1] && plugin[1].extensions ? plugin[1].extensions : config.extensions, - }), { root: [], alias: {}, cwd: projectRootDir }); + const pluginOpts = instances.reduce( + (config, plugin) => ({ + cwd: plugin[1] && plugin[1].cwd ? plugin[1].cwd : config.cwd, + root: config.root.concat(plugin[1] && plugin[1].root ? plugin[1].root : []), + alias: Object.assign(config.alias, plugin[1] ? plugin[1].alias : {}), + extensions: plugin[1] && plugin[1].extensions ? plugin[1].extensions : config.extensions, + }), + { root: [], alias: {}, cwd: projectRootDir }, + ); const babelState = { file: { @@ -68,20 +87,19 @@ exports.resolve = (source, file, opts) => { }; normalizeOptions(babelState.opts, babelState.file); - const src = getRealPath(source, babelState); + + const finalSource = stripWebpack(source); + const src = getRealPath(finalSource, babelState); const extensions = options.extensions || pluginOpts.extensions; return { found: true, - path: resolve.sync( - src || source, - { - ...options, - extensions, - basedir: path.dirname(file), - }, - ), + path: resolve.sync(src || source, { + ...options, + extensions, + basedir: path.dirname(file), + }), }; } catch (e) { return { found: false }; diff --git a/test/index.test.js b/test/index.test.js index fb603cf..4db8db3 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -73,6 +73,32 @@ describe('eslint-import-resolver-module-resolver', () => { .toEqual({ found: true, path: null }); }); + describe('with webpack paths', () => { + it('should support a path with a query', () => { + expect(resolverPlugin.resolve('components/c1?q=sth', path.resolve('./test/examples/components/sub/sub/c2.js'), opts)) + .toEqual({ + found: true, + path: path.resolve(__dirname, './examples/components/c1.js'), + }); + }); + + it('should support a path with a loader', () => { + expect(resolverPlugin.resolve('my-loader!components/c1', path.resolve('./test/examples/components/sub/sub/c2.js'), opts)) + .toEqual({ + found: true, + path: path.resolve(__dirname, './examples/components/c1.js'), + }); + }); + + it('should support multiple loaders', () => { + expect(resolverPlugin.resolve('style-loader!css-loader!less-loader!components/c1', path.resolve('./test/examples/components/sub/sub/c2.js'), opts)) + .toEqual({ + found: true, + path: path.resolve(__dirname, './examples/components/c1.js'), + }); + }); + }); + describe('with specific file extensions', () => { it('should return `false` with a file with an unknown extension', () => { expect(resolverPlugin.resolve('./c3', path.resolve('./test/examples/components/c1'), opts))