From 84fd4f27eb537c9230196d6403aafd406e46e6e9 Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Wed, 19 Oct 2016 17:10:51 +0200 Subject: [PATCH 01/18] Add rule exports-last exports-last will check that all export statements are at the end of the file Closes #620 --- src/index.js | 3 ++ src/rules/exports-last.js | 39 ++++++++++++++++ tests/src/rules/exports-last.js | 82 +++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/rules/exports-last.js create mode 100644 tests/src/rules/exports-last.js diff --git a/src/index.js b/src/index.js index 69cbc2f5e6..e5b36b8f51 100644 --- a/src/index.js +++ b/src/index.js @@ -31,6 +31,9 @@ export const rules = { 'unambiguous': require('./rules/unambiguous'), 'no-unassigned-import': require('./rules/no-unassigned-import'), + // export + 'exports-last': require('./rules/exports-last'), + // metadata-based 'no-deprecated': require('./rules/no-deprecated'), diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js new file mode 100644 index 0000000000..ad80f3a709 --- /dev/null +++ b/src/rules/exports-last.js @@ -0,0 +1,39 @@ +function isExportStatement({ type }) { + // ES Module export statements + if (type === 'ExportDefaultDeclaration' || type === 'ExportNamedDeclaration') { + return true + + // CommonJS export statements + } else if (type === 'ExpressionStatement') { + // TODO + } + + return false +} + +const rule = { + create(context) { + return { + Program({ body }) { + const lastNonExportStatement = body.reduce((acc, node, index) => { + if (isExportStatement(node)) { + return acc + } + return index + }, 0) + + body.forEach((node, index) => { + if (isExportStatement(node) && index < lastNonExportStatement) { + + context.report({ + node, + message: 'Export statements should appear at the end of the file', + }) + } + }) + }, + } + }, +} + +export default rule diff --git a/tests/src/rules/exports-last.js b/tests/src/rules/exports-last.js new file mode 100644 index 0000000000..eddf2191bf --- /dev/null +++ b/tests/src/rules/exports-last.js @@ -0,0 +1,82 @@ +import { test } from '../utils' + +import { RuleTester } from 'eslint' +import rule from 'rules/exports-last' + +const ruleTester = new RuleTester() + +const errors = ['Export statements should appear at the end of the file'] + +ruleTester.run('exports-last', rule, { + valid: [ + test({ + code: ` + const foo = 'bar'; + const bar = 'baz'; + `, + }), + test({ + code: ` + const foo = 'bar'; + export {foo}; + `, + }), + test({ + code: ` + const foo = 'bar'; + export default foo; + `, + }), + test({ + code: ` + const foo = 'bar'; + export default foo; + export const bar = true; + `, + }), + // test({ + // code: ` + // const foo = 'bar'; + // module.exports = foo + // `, + // }), + // test({ + // code: ` + // const foo = 'bar'; + // module.exports = foo; + // exports.bar = true + // `, + // }), + + ], + invalid: [ + test({ + code: ` + export default 'bar'; + const bar = true; + `, + errors, + }), + test({ + code: ` + export const foo = 'bar'; + const bar = true; + `, + errors, + }), + // test({ + // code: ` + // module.exports = 'bar'; + // console.log('hi'); + // `, + // errors, + // }), + // test({ + // code: ` + // exports.foo = 'bar'; + // const bar = true; + // `, + // errors, + // }), + ], +}) From 76f1b84c9dbf0b7fec33e9c78ebc03e04b6f359d Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Thu, 3 Nov 2016 08:00:26 +0100 Subject: [PATCH 02/18] Add documentation for exports-last --- CHANGELOG.md | 3 +++ README.md | 2 ++ docs/rules/exports-last.md | 41 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 docs/rules/exports-last.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 648e481dff..f8a678c8ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - Properly report [`newline-after-import`] when next line is a decorator - Fixed documentation for the default values for the [`order`] rule ([#601]) +### Added +- [`exports-last`] lints that export statements are at the end of the file ([#620] + [#632]) + ## [2.0.1] - 2016-10-06 ### Fixed - Fixed code that relied on removed dependencies. ([#604]) diff --git a/README.md b/README.md index c8c3789aa8..3abbbde609 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a **Style guide:** * Ensure all imports appear before other statements ([`first`]) +* Ensure all exports appear after other statements ([`exports-last`]) * Report repeated import of the same module in multiple places ([`no-duplicates`]) * Report namespace imports ([`no-namespace`]) * Ensure consistent use of file extension within the import path ([`extensions`]) @@ -79,6 +80,7 @@ This plugin intends to support linting of ES2015+ (ES6+) import/export syntax, a * Forbid anonymous values as default exports ([`no-anonymous-default-export`]) [`first`]: ./docs/rules/first.md +[`exports-last`]: ./docs/rules/exports-last.md [`no-duplicates`]: ./docs/rules/no-duplicates.md [`no-namespace`]: ./docs/rules/no-namespace.md [`extensions`]: ./docs/rules/extensions.md diff --git a/docs/rules/exports-last.md b/docs/rules/exports-last.md new file mode 100644 index 0000000000..9629ba9d02 --- /dev/null +++ b/docs/rules/exports-last.md @@ -0,0 +1,41 @@ +# exports-last + +This rule reports all export declaration which come before any non-export statements. + +## This will be reported + +```JS + +const bool = true + +export default bool + +const str = 'foo' + +``` + +```JS + +export const bool = true + +const str = 'foo' + +``` + +## This will not be reported + +```JS +export const bool = true + +export default bool + +export function func() { + console.log('Hello World 🌍') +} + +export const str = 'foo' +``` + +## When Not To Use It + +If you don't mind exports being sprinkled throughout a file, you may not want to enable this rule. From 0de28bd80ad98f1fb2973c2231a970f4fb19ada6 Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Wed, 14 Dec 2016 20:52:01 +0100 Subject: [PATCH 03/18] Remove CommonJS exports --- src/rules/exports-last.js | 4 ---- tests/src/rules/exports-last.js | 27 --------------------------- 2 files changed, 31 deletions(-) diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js index ad80f3a709..ed2e03af2d 100644 --- a/src/rules/exports-last.js +++ b/src/rules/exports-last.js @@ -2,10 +2,6 @@ function isExportStatement({ type }) { // ES Module export statements if (type === 'ExportDefaultDeclaration' || type === 'ExportNamedDeclaration') { return true - - // CommonJS export statements - } else if (type === 'ExpressionStatement') { - // TODO } return false diff --git a/tests/src/rules/exports-last.js b/tests/src/rules/exports-last.js index eddf2191bf..2763fa7f18 100644 --- a/tests/src/rules/exports-last.js +++ b/tests/src/rules/exports-last.js @@ -34,19 +34,6 @@ ruleTester.run('exports-last', rule, { export const bar = true; `, }), - // test({ - // code: ` - // const foo = 'bar'; - // module.exports = foo - // `, - // }), - // test({ - // code: ` - // const foo = 'bar'; - // module.exports = foo; - // exports.bar = true - // `, - // }), ], invalid: [ @@ -64,19 +51,5 @@ ruleTester.run('exports-last', rule, { `, errors, }), - // test({ - // code: ` - // module.exports = 'bar'; - // console.log('hi'); - // `, - // errors, - // }), - // test({ - // code: ` - // exports.foo = 'bar'; - // const bar = true; - // `, - // errors, - // }), ], }) From 0611e2139af97b644f5898b0a8aedf051e211d8e Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Thu, 15 Dec 2016 16:58:31 +0100 Subject: [PATCH 04/18] Refactor exports-last rule --- src/rules/exports-last.js | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js index ed2e03af2d..1cc0334699 100644 --- a/src/rules/exports-last.js +++ b/src/rules/exports-last.js @@ -1,32 +1,24 @@ -function isExportStatement({ type }) { - // ES Module export statements - if (type === 'ExportDefaultDeclaration' || type === 'ExportNamedDeclaration') { - return true - } - - return false -} +const isExportStatement = ({ type }) => + type === 'ExportDefaultDeclaration' + || type === 'ExportNamedDeclaration' + || type === 'ExportAllDeclaration' const rule = { create(context) { return { Program({ body }) { - const lastNonExportStatement = body.reduce((acc, node, index) => { - if (isExportStatement(node)) { - return acc - } - return index - }, 0) - - body.forEach((node, index) => { - if (isExportStatement(node) && index < lastNonExportStatement) { + const firstExportStatementIndex = body.findIndex(isExportStatement) - context.report({ - node, - message: 'Export statements should appear at the end of the file', - }) - } - }) + if (firstExportStatementIndex !== -1) { + body.slice(firstExportStatementIndex).forEach((node) => { + if (!isExportStatement(node)) { + context.report({ + node, + message: 'Export statements should appear at the end of the file', + }) + } + }) + } }, } }, From 531d04dc35f6175ef5559be39e266ff2ffd4477c Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Thu, 15 Dec 2016 17:02:15 +0100 Subject: [PATCH 05/18] Add ES6 only hint to the docs --- docs/rules/exports-last.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/rules/exports-last.md b/docs/rules/exports-last.md index 9629ba9d02..9c7b0dd2d4 100644 --- a/docs/rules/exports-last.md +++ b/docs/rules/exports-last.md @@ -2,6 +2,7 @@ This rule reports all export declaration which come before any non-export statements. + ## This will be reported ```JS @@ -39,3 +40,9 @@ export const str = 'foo' ## When Not To Use It If you don't mind exports being sprinkled throughout a file, you may not want to enable this rule. + +#### ES6 exports only + +The exports-last rule is currently only working on ES6 exports. You may not want to enable this rule if you're using CommonJS exports. + +If you need CommonJS support feel free to open an issue or create a PR. From baa585dc173efea1f37e1c082e3d99da322852dd Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Thu, 15 Dec 2016 17:20:04 +0100 Subject: [PATCH 06/18] Add more tests for exports-last --- tests/src/rules/exports-last.js | 90 ++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 14 deletions(-) diff --git a/tests/src/rules/exports-last.js b/tests/src/rules/exports-last.js index 2763fa7f18..4d8fab5ce4 100644 --- a/tests/src/rules/exports-last.js +++ b/tests/src/rules/exports-last.js @@ -9,45 +9,107 @@ const errors = ['Export statements should appear at the end of the file'] ruleTester.run('exports-last', rule, { valid: [ + // Empty file test({ + code: '', + }), + test({ + // No exports code: ` - const foo = 'bar'; - const bar = 'baz'; + const foo = 'bar' + const bar = 'baz' `, }), test({ code: ` - const foo = 'bar'; - export {foo}; + const foo = 'bar' + export {foo} `, }), test({ code: ` - const foo = 'bar'; - export default foo; + const foo = 'bar' + export default foo `, }), + // Only exports test({ code: ` - const foo = 'bar'; - export default foo; - export const bar = true; + export default foo + export const bar = true + `, + }), + test({ + code: ` + const foo = 'bar' + export default foo + export const bar = true + `, + }), + // Multiline export + test({ + code: ` + const foo = 'bar' + export default function foo () { + const very = 'multiline' + } + export const bar = true + `, + }), + // Many exports + test({ + code: ` + const foo = 'bar' + export default foo + export const so = 'many' + export const exports = ':)' + export const i = 'cant' + export const even = 'count' + export const how = 'many' + `, + }), + // Export all + test({ + code: ` + export * from './foo' `, }), - ], invalid: [ + // Default export before variable declaration + test({ + code: ` + export default 'bar' + const bar = true + `, + errors, + }), + // Named export before variable declaration + test({ + code: ` + export const foo = 'bar' + const bar = true + `, + errors, + }), + // Export all before variable declaration test({ code: ` - export default 'bar'; - const bar = true; + export * from './foo' + const bar = true `, errors, }), + // Many exports arround variable declaration test({ code: ` - export const foo = 'bar'; - const bar = true; + export default 'such foo many bar' + export const so = 'many' + const foo = 'bar' + export const exports = ':)' + export const i = 'cant' + export const even = 'count' + export const how = 'many' `, errors, }), From 8c0e7d62d485cb7b3a8e6d1ccb484de423c22a7c Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Wed, 25 Jan 2017 16:29:15 +0100 Subject: [PATCH 07/18] Refactor exports-last --- CHANGELOG.md | 7 ++----- docs/rules/exports-last.md | 4 +++- src/rules/exports-last.js | 30 +++++++++++++++++------------- tests/src/rules/exports-last.js | 19 +++++++++++++------ 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8a678c8ad..bacbc67d69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] ### Added - [`no-anonymous-default-export`] rule: report anonymous default exports ([#712], thanks [@duncanbeevers]). -- Add new value to [`order`]'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) -- Add `count` option to the [`newline-after-import`] rule to allow configuration of number of newlines expected ([#742], thanks [@ntdb]) +- Add new value to `order`'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) +- [`exports-last`] lints that export statements are at the end of the file ([#620] + [#632]) ### Changed - [`no-extraneous-dependencies`]: use `read-pkg-up` to simplify finding + loading `package.json` ([#680], thanks [@wtgtybhertgeghgtwtg]) @@ -36,9 +36,6 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - Properly report [`newline-after-import`] when next line is a decorator - Fixed documentation for the default values for the [`order`] rule ([#601]) -### Added -- [`exports-last`] lints that export statements are at the end of the file ([#620] + [#632]) - ## [2.0.1] - 2016-10-06 ### Fixed - Fixed code that relied on removed dependencies. ([#604]) diff --git a/docs/rules/exports-last.md b/docs/rules/exports-last.md index 9c7b0dd2d4..22b654d2ea 100644 --- a/docs/rules/exports-last.md +++ b/docs/rules/exports-last.md @@ -1,6 +1,6 @@ # exports-last -This rule reports all export declaration which come before any non-export statements. +This rule enforces that all exports are declared at the bottom of the file. This rule will report any export declarations that comes before any non-export statements. ## This will be reported @@ -26,6 +26,8 @@ const str = 'foo' ## This will not be reported ```JS +const arr = ['bar'] + export const bool = true export default bool diff --git a/src/rules/exports-last.js b/src/rules/exports-last.js index 1cc0334699..91af6b421d 100644 --- a/src/rules/exports-last.js +++ b/src/rules/exports-last.js @@ -1,17 +1,23 @@ -const isExportStatement = ({ type }) => - type === 'ExportDefaultDeclaration' - || type === 'ExportNamedDeclaration' - || type === 'ExportAllDeclaration' +function isNonExportStatement({ type }) { + return type !== 'ExportDefaultDeclaration' && + type !== 'ExportNamedDeclaration' && + type !== 'ExportAllDeclaration' +} -const rule = { - create(context) { +module.exports = { + create: function (context) { return { - Program({ body }) { - const firstExportStatementIndex = body.findIndex(isExportStatement) + Program: function ({ body }) { + const lastNonExportStatementIndex = body.reduce(function findLastIndex(acc, item, index) { + if (isNonExportStatement(item)) { + return index + } + return acc + }, -1) - if (firstExportStatementIndex !== -1) { - body.slice(firstExportStatementIndex).forEach((node) => { - if (!isExportStatement(node)) { + if (lastNonExportStatementIndex !== -1) { + body.slice(0, lastNonExportStatementIndex).forEach(function checkNonExport(node) { + if (!isNonExportStatement(node)) { context.report({ node, message: 'Export statements should appear at the end of the file', @@ -23,5 +29,3 @@ const rule = { } }, } - -export default rule diff --git a/tests/src/rules/exports-last.js b/tests/src/rules/exports-last.js index 4d8fab5ce4..c3c26fdfc7 100644 --- a/tests/src/rules/exports-last.js +++ b/tests/src/rules/exports-last.js @@ -5,13 +5,17 @@ import rule from 'rules/exports-last' const ruleTester = new RuleTester() -const errors = ['Export statements should appear at the end of the file'] +const error = type => ({ + ruleId: 'exports-last', + message: 'Export statements should appear at the end of the file', + type +}); ruleTester.run('exports-last', rule, { valid: [ // Empty file test({ - code: '', + code: '// comment', }), test({ // No exports @@ -82,7 +86,7 @@ ruleTester.run('exports-last', rule, { export default 'bar' const bar = true `, - errors, + errors: [error('ExportDefaultDeclaration')], }), // Named export before variable declaration test({ @@ -90,7 +94,7 @@ ruleTester.run('exports-last', rule, { export const foo = 'bar' const bar = true `, - errors, + errors: [error('ExportNamedDeclaration')], }), // Export all before variable declaration test({ @@ -98,7 +102,7 @@ ruleTester.run('exports-last', rule, { export * from './foo' const bar = true `, - errors, + errors: [error('ExportAllDeclaration')], }), // Many exports arround variable declaration test({ @@ -111,7 +115,10 @@ ruleTester.run('exports-last', rule, { export const even = 'count' export const how = 'many' `, - errors, + errors: [ + error('ExportDefaultDeclaration'), + error('ExportNamedDeclaration'), + ], }), ], }) From 8d4e25edde10748ca5f2a4107fd12b22d6c982c8 Mon Sep 17 00:00:00 2001 From: Konstantin Pschera Date: Wed, 1 Mar 2017 20:20:57 +0100 Subject: [PATCH 08/18] Fix Changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bacbc67d69..f2d2c7d7cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] ### Added - [`no-anonymous-default-export`] rule: report anonymous default exports ([#712], thanks [@duncanbeevers]). -- Add new value to `order`'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) +- Add new value to [`order`]'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) +- Add `count` option to the [`newline-after-import`] rule to allow configuration of number of newlines expected ([#742], thanks [@ntdb]) - [`exports-last`] lints that export statements are at the end of the file ([#620] + [#632]) ### Changed From 5fd356da8abbcfec7c6108825646bbe34074acf1 Mon Sep 17 00:00:00 2001 From: LaySent Date: Thu, 1 Jun 2017 08:20:23 +0800 Subject: [PATCH 09/18] Fix issue #720 Simply prevent eslint to check any parent folder of current working directory. --- utils/resolve.js | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/resolve.js b/utils/resolve.js index 1d6e164b15..8193e77314 100644 --- a/utils/resolve.js +++ b/utils/resolve.js @@ -21,6 +21,7 @@ exports.fileExistsWithCaseSync = function fileExistsWithCaseSync(filepath, cache // null means it resolved to a builtin if (filepath === null) return true + if (filepath.toLowerCase() === process.cwd().toLowerCase()) return true const parsedPath = path.parse(filepath) , dir = parsedPath.dir From ac3d76a5157142487001af43c9e8154fc2e097d2 Mon Sep 17 00:00:00 2001 From: LaySent Date: Thu, 1 Jun 2017 12:21:04 +0800 Subject: [PATCH 10/18] Add unit test --- tests/src/core/resolve.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index e8f255f345..71791c500d 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -3,6 +3,7 @@ import { expect } from 'chai' import resolve, { CASE_SENSITIVE_FS, fileExistsWithCaseSync } from 'eslint-module-utils/resolve' import ModuleCache from 'eslint-module-utils/ModuleCache' +import * as path from 'path' import * as fs from 'fs' import * as utils from '../utils' @@ -43,6 +44,11 @@ describe('resolve', function () { expect(fileExistsWithCaseSync(file, ModuleCache.getSettings(testContext))) .to.be.false }) + it('detecting case does not include parent folder path (issue #720)', function () { + const f = path.join(process.cwd().toUpperCase(), './tests/files/jsx/MyUnCoolComponent.jsx') + expect(fileExistsWithCaseSync(f, ModuleCache.getSettings(testContext), true)) + .to.be.true + }) }) describe('rename cache correctness', function () { From dbc9ec735d9fd32ae69499c235f2a0deb106be94 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 14:47:01 -0600 Subject: [PATCH 11/18] bugfix: #886 --- src/core/importType.js | 3 ++- tests/src/core/importType.js | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index 23bc6350d0..c196ecd397 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -13,8 +13,9 @@ export function isAbsolute(name) { } export function isBuiltIn(name, settings) { + const baseModule = name.split('/')[0] const extras = (settings && settings['import/core-modules']) || [] - return builtinModules.indexOf(name) !== -1 || extras.indexOf(name) > -1 + return builtinModules.indexOf(baseModule) !== -1 || extras.indexOf(baseModule) > -1 } function isExternalPath(path, name, settings) { diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 5b63910af1..e5e6f85ea4 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe('importType(name)', function () { +describe.only('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { @@ -74,6 +74,11 @@ describe('importType(name)', function () { expect(importType('electron', electronContext)).to.equal('builtin') }) + it("should return 'builtin' for resources inside additional core modules", function() { + const electronContext = testContext({ 'import/core-modules': ['electron'] }) + expect(importType('electron/some/path/to/resource.json', 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') }) From 307ddeb587ce5abc382e9c827da045f0e5dcb292 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 14:49:52 -0600 Subject: [PATCH 12/18] cleanup: no exclusive tests --- tests/src/core/importType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index e5e6f85ea4..20bdd676dc 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe.only('importType(name)', function () { +describe('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { From ed65a7412a90f4e3cf475efaff7a8ea001d6adc1 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 15:47:24 -0600 Subject: [PATCH 13/18] logic: improve scoped module scoping --- src/core/importType.js | 13 +++++++++++-- tests/src/core/importType.js | 9 ++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index c196ecd397..cc97de0d3f 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -8,14 +8,23 @@ function constant(value) { return () => value } +function baseModule(name) { + if (isScoped(name)) { + const [scope, pkg] = name.split('/') + return `${scope}/${pkg}` + } + const [pkg] = name.split('/') + return pkg +} + export function isAbsolute(name) { return name.indexOf('/') === 0 } export function isBuiltIn(name, settings) { - const baseModule = name.split('/')[0] + const base = baseModule(name) const extras = (settings && settings['import/core-modules']) || [] - return builtinModules.indexOf(baseModule) !== -1 || extras.indexOf(baseModule) > -1 + return builtinModules.indexOf(base) !== -1 || extras.indexOf(base) > -1 } function isExternalPath(path, name, settings) { diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 20bdd676dc..6f6c1ea73f 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe('importType(name)', function () { +describe.only('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { @@ -69,14 +69,21 @@ describe('importType(name)', function () { it("should return 'builtin' for additional core modules", function() { // without extra config, should be marked external expect(importType('electron', context)).to.equal('external') + expect(importType('@org/foobar', context)).to.equal('external') const electronContext = testContext({ 'import/core-modules': ['electron'] }) expect(importType('electron', electronContext)).to.equal('builtin') + + const scopedContext = testContext({ 'import/core-modules': ['@org/foobar'] }) + expect(importType('@org/foobar', scopedContext)).to.equal('builtin') }) it("should return 'builtin' for resources inside additional core modules", function() { const electronContext = testContext({ 'import/core-modules': ['electron'] }) expect(importType('electron/some/path/to/resource.json', electronContext)).to.equal('builtin') + + const scopedContext = testContext({ 'import/core-modules': ['@org/foobar'] }) + expect(importType('@org/foobar/some/path/to/resource.json', scopedContext)).to.equal('builtin') }) it("should return 'external' for module from 'node_modules' with default config", function() { From 2f2dfb0a818f0c5cc6f5939627568636548bce97 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 15:48:12 -0600 Subject: [PATCH 14/18] cleanup: no exclusive tests --- tests/src/core/importType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 6f6c1ea73f..1a4816d1a7 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe.only('importType(name)', function () { +describe('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { From 146f87f0b3cc7684f38b384a77e2b02b8b907288 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Sun, 27 Aug 2017 15:40:00 -0400 Subject: [PATCH 15/18] changelog notes for #720 + #858 --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bbb880e06..439ec9e754 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,12 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] - +### Changed +- Case-sensitivity checking ignores working directory and ancestors. ([#720] + [#858], thanks [@laysent]) ## [2.7.0] - 2017-07-06 ### Changed -- [`no-absolute-path`] picks up speed boost, optional AMD support ([#843], thansk [@jseminck]) +- [`no-absolute-path`] picks up speed boost, optional AMD support ([#843], thanks [@jseminck]) ## [2.6.1] - 2017-06-29 ### Fixed @@ -421,6 +422,7 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#858]: https://github.com/benmosher/eslint-plugin-import/pull/858 [#843]: https://github.com/benmosher/eslint-plugin-import/pull/843 [#871]: https://github.com/benmosher/eslint-plugin-import/pull/871 [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 @@ -484,6 +486,7 @@ for info on changes for earlier releases. [#863]: https://github.com/benmosher/eslint-plugin-import/issues/863 [#839]: https://github.com/benmosher/eslint-plugin-import/issues/839 +[#720]: https://github.com/benmosher/eslint-plugin-import/issues/720 [#686]: https://github.com/benmosher/eslint-plugin-import/issues/686 [#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 @@ -633,3 +636,4 @@ for info on changes for earlier releases. [@eelyafi]: https://github.com/eelyafi [@mastilver]: https://github.com/mastilver [@jseminck]: https://github.com/jseminck +[@laysent]: https://github.com/laysent From 1ba1c3a05251099d8422a81159bac9d72780c132 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Sun, 27 Aug 2017 15:51:35 -0400 Subject: [PATCH 16/18] removing changelog note, will re-add --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f2d2c7d7cf..648e481dff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-anonymous-default-export`] rule: report anonymous default exports ([#712], thanks [@duncanbeevers]). - Add new value to [`order`]'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) - Add `count` option to the [`newline-after-import`] rule to allow configuration of number of newlines expected ([#742], thanks [@ntdb]) -- [`exports-last`] lints that export statements are at the end of the file ([#620] + [#632]) ### Changed - [`no-extraneous-dependencies`]: use `read-pkg-up` to simplify finding + loading `package.json` ([#680], thanks [@wtgtybhertgeghgtwtg]) From 5f5fbf6d12518e6a654c37475e9fe2644b008066 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Sun, 27 Aug 2017 15:55:16 -0400 Subject: [PATCH 17/18] changelog notes for #620 + #632 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 439ec9e754..2942f9bd8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] +### Added +- [`exports-last`] rule ([#620] + [#632], thanks [@k15a]) + ### Changed - Case-sensitivity checking ignores working directory and ancestors. ([#720] + [#858], thanks [@laysent]) @@ -419,6 +422,7 @@ for info on changes for earlier releases. [`no-unassigned-import`]: ./docs/rules/no-unassigned-import.md [`unambiguous`]: ./docs/rules/unambiguous.md [`no-anonymous-default-export`]: ./docs/rules/no-anonymous-default-export.md +[`exports-last`]: ./docs/rules/exports-last.md [`memo-parser`]: ./memo-parser/README.md @@ -433,6 +437,7 @@ for info on changes for earlier releases. [#680]: https://github.com/benmosher/eslint-plugin-import/pull/680 [#654]: https://github.com/benmosher/eslint-plugin-import/pull/654 [#639]: https://github.com/benmosher/eslint-plugin-import/pull/639 +[#632]: https://github.com/benmosher/eslint-plugin-import/pull/632 [#630]: https://github.com/benmosher/eslint-plugin-import/pull/630 [#628]: https://github.com/benmosher/eslint-plugin-import/pull/628 [#596]: https://github.com/benmosher/eslint-plugin-import/pull/596 @@ -492,6 +497,7 @@ for info on changes for earlier releases. [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 [#653]: https://github.com/benmosher/eslint-plugin-import/issues/653 [#627]: https://github.com/benmosher/eslint-plugin-import/issues/627 +[#620]: https://github.com/benmosher/eslint-plugin-import/issues/620 [#609]: https://github.com/benmosher/eslint-plugin-import/issues/609 [#604]: https://github.com/benmosher/eslint-plugin-import/issues/604 [#602]: https://github.com/benmosher/eslint-plugin-import/issues/602 From 68f63f59538ceeb4f0348185683839be94d152c2 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Sun, 27 Aug 2017 15:55:56 -0400 Subject: [PATCH 18/18] =?UTF-8?q?forgot=20@k15a's=20user=20link=20?= =?UTF-8?q?=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2942f9bd8e..20814d81f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -643,3 +643,4 @@ for info on changes for earlier releases. [@mastilver]: https://github.com/mastilver [@jseminck]: https://github.com/jseminck [@laysent]: https://github.com/laysent +[@k15a]: https://github.com/k15a