Skip to content

Commit

Permalink
[New] order rule: add option pathGroupsExcludedImportTypes to allow…
Browse files Browse the repository at this point in the history
… ordering of external import types
  • Loading branch information
Mairu authored and ljharb committed Dec 14, 2019
1 parent 982493d commit 16ae652
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 8 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Expand Up @@ -16,6 +16,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
- [`no-extraneous-dependencies`]: ensure `node.source` is truthy ([#1589], thanks [@ljharb])
- [`extensions`]: Ignore query strings when checking for extensions ([#1572], thanks [@pcorpet])

### Added
- [`order`]: add option pathGroupsExcludedImportTypes to allow ordering of external import types ([#1565], thanks [@Mairu])

## [2.19.1] - 2019-12-08
### Fixed
- [`no-extraneous-dependencies`]: ensure `node.source` exists
Expand Down Expand Up @@ -789,6 +792,7 @@ for info on changes for earlier releases.
[#211]: https://github.com/benmosher/eslint-plugin-import/pull/211
[#164]: https://github.com/benmosher/eslint-plugin-import/pull/164
[#157]: https://github.com/benmosher/eslint-plugin-import/pull/157
[#1565]: https://github.com/benmosher/eslint-plugin-import/issues/1565
[#1366]: https://github.com/benmosher/eslint-plugin-import/issues/1366
[#1334]: https://github.com/benmosher/eslint-plugin-import/issues/1334
[#1323]: https://github.com/benmosher/eslint-plugin-import/issues/1323
Expand Down
24 changes: 23 additions & 1 deletion docs/rules/order.md
Expand Up @@ -96,7 +96,7 @@ You can set the options like this:

### `pathGroups: [array of objects]`:

To be able so group by paths mostly needed with aliases pathGroups can be defined.
To be able to group by paths mostly needed with aliases pathGroups can be defined.

Properties of the objects

Expand All @@ -120,6 +120,28 @@ Properties of the objects
}
```

### `pathGroupsExcludedImportTypes: [array]`:

This defines import types that are not handled by configured pathGroups.
This is mostly needed when you want to handle path groups that look like external imports.

Example:
```json
{
"import/order": ["error", {
"pathGroups": [
{
"pattern": "@app/**",
"group": "external",
"position": "after"
}
],
"pathGroupsExcludedImportTypes": ["builtin"]
}]
}
```
The default value is `["builtin", "external"]`.

### `newlines-between: [ignore|always|always-and-inside-groups|never]`:

Enforces or forbids new lines between import groups:
Expand Down
34 changes: 27 additions & 7 deletions src/rules/order.js
Expand Up @@ -269,7 +269,7 @@ function importsSorterDesc(importA, importB) {

function mutateRanksToAlphabetize(imported, alphabetizeOptions) {
const groupedByRanks = imported.reduce(function(acc, importedItem) {
if (!Array.isArray(acc[importedItem.rank])) {
if (!Array.isArray(acc[importedItem.rank])) {
acc[importedItem.rank] = []
}
acc[importedItem.rank].push(importedItem.name)
Expand Down Expand Up @@ -312,10 +312,10 @@ function computePathRank(ranks, pathGroups, path, maxPosition) {
}
}

function computeRank(context, ranks, name, type) {
function computeRank(context, ranks, name, type, excludedImportTypes) {
const impType = importType(name, context)
let rank
if (impType !== 'builtin' && impType !== 'external') {
if (!excludedImportTypes.has(impType)) {
rank = computePathRank(ranks.groups, ranks.pathGroups, name, ranks.maxPosition)
}
if (!rank) {
Expand All @@ -328,8 +328,8 @@ function computeRank(context, ranks, name, type) {
return rank
}

function registerNode(context, node, name, type, ranks, imported) {
const rank = computeRank(context, ranks, name, type)
function registerNode(context, node, name, type, ranks, imported, excludedImportTypes) {
const rank = computeRank(context, ranks, name, type, excludedImportTypes)
if (rank !== -1) {
imported.push({name, rank, node})
}
Expand Down Expand Up @@ -508,6 +508,9 @@ module.exports = {
groups: {
type: 'array',
},
pathGroupsExcludedImportTypes: {
type: 'array',
},
pathGroups: {
type: 'array',
items: {
Expand Down Expand Up @@ -562,6 +565,7 @@ module.exports = {
create: function importOrderRule (context) {
const options = context.options[0] || {}
const newlinesBetweenImports = options['newlines-between'] || 'ignore'
const pathGroupsExcludedImportTypes = new Set(options['pathGroupsExcludedImportTypes'] || ['builtin', 'external'])
const alphabetize = getAlphabetizeConfig(options)
let ranks

Expand Down Expand Up @@ -594,15 +598,31 @@ module.exports = {
ImportDeclaration: function handleImports(node) {
if (node.specifiers.length) { // Ignoring unassigned imports
const name = node.source.value
registerNode(context, node, name, 'import', ranks, imported)
registerNode(
context,
node,
name,
'import',
ranks,
imported,
pathGroupsExcludedImportTypes
)
}
},
CallExpression: function handleRequires(node) {
if (level !== 0 || !isStaticRequire(node) || !isInVariableDeclarator(node.parent)) {
return
}
const name = node.arguments[0].value
registerNode(context, node, name, 'require', ranks, imported)
registerNode(
context,
node,
name,
'require',
ranks,
imported,
pathGroupsExcludedImportTypes
)
},
'Program:exit': function reportAndReset() {
if (newlinesBetweenImports !== 'ignore') {
Expand Down
22 changes: 22 additions & 0 deletions tests/src/rules/order.js
Expand Up @@ -276,6 +276,28 @@ ruleTester.run('order', rule, {
],
}],
}),
// Using pathGroups to customize ordering for imports that are recognized as 'external'
// by setting pathGroupsExcludedImportTypes without 'external'
test({
code: `
import fs from 'fs';
import { Input } from '@app/components/Input';
import { Button } from '@app2/components/Button';
import _ from 'lodash';
import { add } from './helper';`,
options: [{
'newlines-between': 'always',
pathGroupsExcludedImportTypes: ['builtin'],
pathGroups: [
{ pattern: '@app/**', group: 'external', position: 'before' },
{ pattern: '@app2/**', group: 'external', position: 'before' },
],
}],
}),

// Option: newlines-between: 'always'
test({
Expand Down

0 comments on commit 16ae652

Please sign in to comment.