-
Notifications
You must be signed in to change notification settings - Fork 4
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:
-
maxLineLengthwill be set to code (default 80). -
wrappingStyle.ignoreCommentswill be true if either ignoreComments or ignoreTrailingComments is true (Both default to false).- Except when
wrappingStyleis 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",insertFinalNewlinewill be false. - Otherwise,
insertFinalNewlinewill 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",hasSemicolonwill be true. - Otherwise,
hasSemicolonwill 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",trailingCommawill be none. - When the option is
"always",trailingCommawill be always. - When the option is
"always-multiline","only-multiline"or"ignore",trailingCommawill be multiLine. - When the option is an object, only
importsis considered:- When
importsis"never",trailingCommawill be none. - When
importsis"always",trailingCommawill be always. - When
importsis"always-multiline","only-multiline"or"ignore",trailingCommawill be multiLine.
- When
@typescript-eslint/comma-dangle is also supported in the same way.
Notes:
-
exportsin the option object is ignored.
Enforces consistent spacing inside braces.
If enabled, bracketSpacing from Configuration will be overridden:
- When the string option is
"never",bracketSpacingwill be false. - When the string option is
"always",bracketSpacingwill 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.