diff --git a/lib/options-manager.js b/lib/options-manager.js index f9758ae5..11371986 100644 --- a/lib/options-manager.js +++ b/lib/options-manager.js @@ -5,6 +5,7 @@ const arrify = require('arrify'); const mergeWith = require('lodash.mergewith'); const multimatch = require('multimatch'); const pathExists = require('path-exists'); +const findUp = require('find-up'); const pkgConf = require('pkg-conf'); const findCacheDir = require('find-cache-dir'); const resolveFrom = require('resolve-from'); @@ -243,8 +244,30 @@ const buildConfig = options => { Object.assign(config.rules, options.rules); } - if (options.settings) { - config.baseConfig.settings = options.settings; + config.baseConfig.settings = Object.assign({}, options.settings); + let importResolver = config.baseConfig.settings['import/resolver'] || {}; + + // Convert import/resolver: 'x' => import/resolver: {x: {}} + if (typeof importResolver === 'string') { + const resolverName = importResolver; + importResolver = {}; + importResolver[resolverName] = {}; + } + + if (options.webpack) { + importResolver.webpack = options.webpack === true ? {} : options.webpack; + } else if (!importResolver.webpack) { + // If a webpack config file exists, add the import resolver automatically + const webpackConfigPath = findUp.sync('webpack.config.js', {cwd: options.cwd}); + if (webpackConfigPath) { + importResolver.webpack = {config: webpackConfigPath}; + } + } + + if (Object.keys(importResolver).length > 0) { + config.baseConfig.settings['import/resolver'] = importResolver; + } else { + delete config.baseConfig.settings['import/resolver']; } if (options.parser) { diff --git a/package.json b/package.json index 13f09fe2..77c81622 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "eslint-config-prettier": "^3.3.0", "eslint-config-xo": "^0.26.0", "eslint-formatter-pretty": "^2.0.0", + "eslint-import-resolver-webpack": "^0.11.0", "eslint-plugin-ava": "^5.1.0", "eslint-plugin-eslint-comments": "^3.0.1", "eslint-plugin-import": "^2.14.0", @@ -64,6 +65,7 @@ "eslint-plugin-promise": "^4.0.0", "eslint-plugin-unicorn": "^7.0.0", "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", "get-stdin": "^6.0.0", "globby": "^9.0.0", "has-flag": "^3.0.0", diff --git a/readme.md b/readme.md index 25e37078..3d42733b 100644 --- a/readme.md +++ b/readme.md @@ -266,6 +266,13 @@ Enforce ES2015+ rules. Disabling this will make it not *enforce* ES2015+ syntax *ES2015+ is parsed even without this option. You can already use ES2017 features like [`async`/`await`](https://github.com/lukehoban/ecmascript-asyncawait). +### webpack + +Type: `boolean`, `Object` + +Enable the ESLint webpack import resolver plugin. Value can be an `Object` with plugin configuration. + +See [eslint-import-resolver-webpack](https://www.npmjs.com/package/eslint-import-resolver-webpack) ## TypeScript and Flow diff --git a/test/options-manager.js b/test/options-manager.js index 9f8f512d..afde2685 100644 --- a/test/options-manager.js +++ b/test/options-manager.js @@ -342,11 +342,23 @@ test('buildConfig: parser', t => { }); test('buildConfig: settings', t => { - const settings = {'import/resolver': 'webpack'}; + const settings = {'import/resolver': {webpack: {}}}; const config = manager.buildConfig({settings}); t.deepEqual(config.baseConfig.settings, settings); }); +test('buildConfig: finds webpack config file', t => { + const cwd = path.resolve('fixtures', 'webpack-config'); + const config = manager.buildConfig({cwd}); + const expected = {webpack: {config: path.resolve(cwd, 'webpack.config.js')}}; + t.deepEqual(config.baseConfig.settings['import/resolver'], expected); +}); + +test('buildConfig: webpack option sets resolver', t => { + const config = manager.buildConfig({webpack: true, settings: {'import/resolver': 'node'}}); + t.deepEqual(config.baseConfig.settings['import/resolver'], {webpack: {}, node: {}}); +}); + test('buildConfig: extends', t => { const config = manager.buildConfig({extends: [ 'plugin:foo/bar',