diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e0fc2180..956d17dd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] +### Added +- [`import/external-module-folders` setting]: a possibility to configure folders for "external" modules ([#444]) ## [1.11.1] - 2016-07-20 ### Fixed @@ -243,6 +245,7 @@ for info on changes for earlier releases. [`import/ignore` setting]: ./README.md#importignore [`import/extensions` setting]: ./README.md#importextensions [`import/core-modules` setting]: ./README.md#importcore-modules +[`import/external-module-folders` setting]: ./README.md#importexternal-module-folders [`no-unresolved`]: ./docs/rules/no-unresolved.md [`no-deprecated`]: ./docs/rules/no-deprecated.md @@ -264,6 +267,7 @@ for info on changes for earlier releases. [`prefer-default-export`]: ./docs/rules/prefer-default-export.md [`no-restricted-paths`]: ./docs/rules/no-restricted-paths.md +[#444]: https://github.com/benmosher/eslint-plugin-import/pull/444 [#428]: https://github.com/benmosher/eslint-plugin-import/pull/428 [#395]: https://github.com/benmosher/eslint-plugin-import/pull/395 [#371]: https://github.com/benmosher/eslint-plugin-import/pull/371 diff --git a/README.md b/README.md index f3e3c3910..f8d707b43 100644 --- a/README.md +++ b/README.md @@ -260,6 +260,10 @@ that specifies this for you. Contribution of more such shared configs for other platforms are welcome! +#### `import/external-module-folders` + +An array of folders. Resolved modules only from those folders will be considered as "external". By default - `["node_modules"]`. Makes sense if you have configured your path or webpack to handle your internal paths differently and want to considered modules from some folders, for example `bower_components` or `jspm_modules`, as "external". + #### `import/resolver` See [resolvers](#resolvers). diff --git a/docs/rules/order.md b/docs/rules/order.md index dae5ca904..5a542e7b6 100644 --- a/docs/rules/order.md +++ b/docs/rules/order.md @@ -141,3 +141,8 @@ import index from './'; import sibling from './foo'; ``` +## Related + +- [`import/external-module-folders`] setting + +[`import/external-module-folders`]: ../../README.md#importexternal-module-folders diff --git a/src/core/importType.js b/src/core/importType.js index 86f01bc89..02edc0234 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -13,10 +13,14 @@ export function isBuiltIn(name, settings) { return builtinModules.indexOf(name) !== -1 || extras.indexOf(name) > -1 } +function isExternalPath(path, name, settings) { + const folders = (settings && settings['import/external-module-folders']) || ['node_modules'] + return !path || folders.some(folder => -1 < path.indexOf(join(folder, name))) +} + const externalModuleRegExp = /^\w/ function isExternalModule(name, settings, path) { - if (!externalModuleRegExp.test(name)) return false - return (!path || -1 < path.indexOf(join('node_modules', name))) + return externalModuleRegExp.test(name) && isExternalPath(path, name, settings) } const scopedRegExp = /^@\w+\/\w+/ @@ -25,8 +29,7 @@ function isScoped(name) { } function isInternalModule(name, settings, path) { - if (!externalModuleRegExp.test(name)) return false - return (path && -1 === path.indexOf(join('node_modules', name))) + return externalModuleRegExp.test(name) && !isExternalPath(path, name, settings) } function isRelativeToParent(name) { diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 53796ba13..28a8d7f4e 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -66,4 +66,18 @@ describe('importType(name)', function () { const electronContext = testContext({ 'import/core-modules': ['electron'] }) expect(importType('electron', electronContext)).to.equal('builtin') }) + + it("should return 'external' for module from 'node_modules' with default config", function() { + expect(importType('builtin-modules', context)).to.equal('external') + }) + + it("should return 'internal' for module from 'node_modules' if 'node_modules' missed in 'external-module-folders'", function() { + const foldersContext = testContext({ 'import/external-module-folders': [] }) + expect(importType('builtin-modules', foldersContext)).to.equal('internal') + }) + + it("should return 'external' for module from 'node_modules' if 'node_modules' contained in 'external-module-folders'", function() { + const foldersContext = testContext({ 'import/external-module-folders': ['node_modules'] }) + expect(importType('builtin-modules', foldersContext)).to.equal('external') + }) })