-
Notifications
You must be signed in to change notification settings - Fork 3
ESLint Compatibility
- Introduction
- sort-imports
- max-len
- indent
- eol-last
- semi
- comma-dangle
- object-curly-spacing
- import/newline-after-import
- import/no-useless-path-segments
- Ignore Rules
- Limitations
When formatting a source file, formatSourceFromFile will try to search for ESLint config and automatically adjust the result to follow the rules. This is done by translating relevant rules and merging them into the base Configuration provided in parameters.
Currently, the supported rules are:
- sort-imports
- max-len
- indent and @typescript-eslint/indent
- semi and @typescript-eslint/semi
- comma-dangle and @typescript-eslint/comma-dangle
- import/newline-after-import
- import/no-useless-path-segments
For them to work, you need to ensure that:
- ESLint is installed and properly configured.
- The file to format is not ignored/excluded by ESLint or the base Configuration provided in parameters.
- The ESLint rules are in effect, i.e. either
"warn"
or"error"
level.
Note: It's ok that ESLint is not found so this feature is off without any impact.
The ESLint rules might conflict with the base Configuration. In this case, ESLint rules will win to avoid lint errors.
Here is how ESLint rule options are translated and merged to Configuration.
This rule checks all import declarations and verifies that all imports are first sorted by the used member syntax and then alphabetically by the first member or alias name.
If ignoreDeclarationSort
is false
, imports will be grouped and sorted based on allowSeparatedGroups
and memberSyntaxSortOrder
options. The groups and sub-groups from the base Configuration might be disregarded in some situations as described in the next section.
If either ignoreMemberSort
or ignoreDeclarationSort
is false
, binding names within an import will be sorted complying to ESLint and based on ignoreCase
, which means the global sortRules.names
and all groups' sort.names
from the base Configuration will be disregarded.
If both ignoreMemberSort
and ignoreDeclarationSort
are true
, no changes to the base Configuration.
If allowSeparatedGroups
is false
, all imports will be grouped by memberSyntaxSortOrder
instead of groupRules
from the base Configuration, and then sorted by the first binding names or alias regardless of sortImportsBy
from the base Configuration.
For example,
import-sorter.json:
{
"groupRules": ["^a", "^b"]
}
Without ESLint sort-imports rules, imports would be formatted as follows:
// Group "^a"
import A from "a";
import { B, C } from "ab";
// Group "^b"
import { D, E } from "b";
When configuring ESLint with:
.eslintrc.json:
{
"rules": {
"sort-imports": [
"warn",
{
"allowSeparatedGroups": false,
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
}
]
}
}
The result would be:
// Group "multiple"
import { B, C } from "ab";
import { D, E } from "b";
// Group "single"
import A from "a";
If allowSeparatedGroups
is true
, imports will still be grouped by groupRules
from the base Configuration, but sub-grouped by memberSyntaxSortOrder
instead of subGroups
, and then sorted by the first binding names or alias regardless of sortImportsBy
from the base Configuration.
For example,
import-sorter.json:
{
"groupRules": [["^a", "^b"]]
}
Without ESLint sort-import rules, imports would be formatted as:
// Group ["^a", "^b"]
import A from "a"; // Sub-group "^a"
import { B, C } from "ab";
import { D, E } from "b"; // Sub-group "^b"
When configuring ESLint with:
.eslintrc.json:
{
"rules": {
"sort-imports": [
"warn",
{
"allowSeparatedGroups": true,
"memberSyntaxSortOrder": ["none", "all", "multiple", "single"]
}
]
}
}
The result would be:
// Group ["^a", "^b"]
import { B, C } from "ab"; // Sub-group "multiple"
import { D, E } from "b";
import A from "a"; // Sub-group "single"
The translation from a memberSyntaxSortOrder
item to a group/sub-group is as follows:
-
"none"
to{"flags": "scripts"}
, which accepts all script imports; -
"all"
to{"flags": "namespace"}
, which accepts all namespace imports; -
"multiple"
to{"flags": "multiple"}
, which accepts all imports with multiple names, e.g.:import { A, B } from "a"; import C, { D } from "b"; import E, * as F from "c";
-
"single"
to{"flags": "single"}
, which accepts all imports with single name, e.g.:import A from "a"; import { B } from "b";
If false
, the global sortRules.names
and all groups' sort.names
will be replaced with ["AZ", "_", "az"]
.
If true
, the global sortRules.names
and all groups' sort.names
will be replaced with ["_", "aA"]
.
For example,
import-sorter.json:
{
"sortRules": {
"names": ["az", "_", "AZ"]
}
}
// "sort-imports": "off"
import { a, _, A } from "x";
// "sort-imports": ["warn", { "ignoreCase": false }]
import { A, _, a } from "x";
// "sort-imports": ["warn", { "ignoreCase": true }]
import { _, a, A } from "x";
This rule enforces a maximum line length to increase code readability and maintainability.
If on, this rule affects the following options from Configuration:
-
maxLineLength
will be set to code (default 80). -
wrappingStyle.ignoreComments
will be true if either ignoreComments or ignoreTrailingComments is true (Both default to false).- Except when
wrappingStyle
is prettier, in which case ignoreComments and ignoreTrailingComments will be both ignored.
- Except when
In addition, tabWidth (default 4) will be considered when calculating line length if tabType
in Configuration is tab.
Other fields from the rule are ignored.
This rule enforces a consistent indentation style.
If enabled, the 2nd option ("tab" or a number) will impact tabType
and tabSize
in Configuration.
The 3rd option is ignored even though there is an ImportDeclaration field inside, because the use cases that it's not the default (1) are too rare.
@typescript-eslint/indent is also supported in the same way.
This rule enforces at least one newline (or absence thereof) at the end of non-empty files.
When the rule is enabled, insertFinalNewline
from Configuration will be overridden:
- When the option is
"never"
,insertFinalNewline
will be false. - Otherwise,
insertFinalNewline
will be true.
Notes:
-
"unix"
,"windows"
and"always"
options are indistinguishable.
This rule enforces consistent use of semicolons.
When the rule is enabled, hasSemicolon
from Configuration will be overridden:
- When the option is
"always"
,hasSemicolon
will be true. - Otherwise,
hasSemicolon
will be false.
@typescript-eslint/semi is also supported in the same way.
Notes:
- The object option is ignored.
This rule enforces consistent use of trailing commas in object and array literals.
When the rule is enabled, trailingComma
from Configuration will be overridden:
- When the option is
"never"
,trailingComma
will be none. - When the option is
"always"
,trailingComma
will be always. - When the option is
"always-multiline"
,"only-multiline"
or"ignore"
,trailingComma
will be multiLine. - When the option is an object, only
imports
is considered:- When
imports
is"never"
,trailingComma
will be none. - When
imports
is"always"
,trailingComma
will be always. - When
imports
is"always-multiline"
,"only-multiline"
or"ignore"
,trailingComma
will be multiLine.
- When
@typescript-eslint/comma-dangle is also supported in the same way.
Notes:
-
exports
in the option object is ignored.
Enforces consistent spacing inside braces.
If enabled, bracketSpacing
from Configuration will be overridden:
- When the string option is
"never"
,bracketSpacing
will be false. - When the string option is
"always"
,bracketSpacing
will be true.
@typescript-eslint/object-curly-spacing is also supported in the same way.
Notes:
- The object option is ignored.
Enforces having one or more empty lines after the last top-level import statement or require call.
If enabled, the number of empty lines after the last import declaration will be defined by its count
option instead of emptyLinesAfterAllImports
from the base Configuration.
For example,
import-sorter.json:
{
"emptyLinesAfterAllImports": 1
}
// "import/newline-after-import": "off"
import A from "a";
const a = new A();
// "import/newline-after-import": ["error", { "count": 2 }]
import A from "a";
const a = new A();
Use this rule to prevent unnecessary path segments in import and require statements.
When enabled, useless ending slash (/
) will be removed when normalizing import and export paths, regardless of removeLastSlashInPath
from the base Configuration.
If noUselessIndex is set to true
, useless ending index
(and index.js[x]/ts[x]
) will also be removed, regardless of removeLastIndexInPath
from the base Configuration.
For example:
import-sorter.json:
{
"removeLastSlashInPath": false,
"removeLastIndexInPath": false
}
// "import/no-useless-path-segments": "off"
import "a/b/";
import A from "./";
import B from "../";
import { C } from "./c/index";
// "import/no-useless-path-segments": ["error", { "noUselessIndex": false }]
import "a/b";
import A from ".";
import B from "..";
import { C } from "./c/index";
// "import/no-useless-path-segments": ["error", { "noUselessIndex": true }]
import "a/b";
import A from ".";
import B from "..";
import { C } from "./c";
Notes:
- CommonJS imports are NOT supported regardless of commonjs option.
Sometimes you may want to ignore some or all ESLint rules. You can achieve that via ignoreESLintRules. It accepts one or more regular expresses and matches rule names against them.
For example, to ignore all ESLint rules:
import_sorter.json:
{
"ignoreESLintRules": ".*"
}
Or to ignore indent, @typescript-eslint/indent and sort-imports rules:
import_sorter.json:
{
"ignoreESLintRules": ["indent$", "^sort-imports$"]
}
Currently, the inline ESLint disable/enable comments are not recognized, while ignored files and directories are properly handled.