source: frontend/node_modules/eslint-plugin-import/docs/rules/order.md

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 28.9 KB
Line 
1# import/order
2
3🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
4
5<!-- end auto-generated rule header -->
6
7Enforce a convention in the order of `require()` / `import` statements.
8
9With the [`groups`][18] option set to `["builtin", "external", "internal", "parent", "sibling", "index", "object", "type"]` the order is as shown in the following example:
10
11```ts
12// 1. node "builtin" modules
13import fs from 'fs';
14import path from 'path';
15// 2. "external" modules
16import _ from 'lodash';
17import chalk from 'chalk';
18// 3. "internal" modules
19// (if you have configured your path or webpack to handle your internal paths differently)
20import foo from 'src/foo';
21// 4. modules from a "parent" directory
22import foo from '../foo';
23import qux from '../../foo/qux';
24// 5. "sibling" modules from the same or a sibling's directory
25import bar from './bar';
26import baz from './bar/baz';
27// 6. "index" of the current directory
28import main from './';
29// 7. "object"-imports (only available in TypeScript)
30import log = console.log;
31// 8. "type" imports (only available in Flow and TypeScript)
32import type { Foo } from 'foo';
33```
34
35See [here][3] for further details on how imports are grouped.
36
37## Fail
38
39```ts
40import _ from 'lodash';
41import path from 'path'; // `path` import should occur before import of `lodash`
42
43// -----
44
45var _ = require('lodash');
46var path = require('path'); // `path` import should occur before import of `lodash`
47
48// -----
49
50var path = require('path');
51import foo from './foo'; // `import` statements must be before `require` statement
52```
53
54## Pass
55
56```ts
57import path from 'path';
58import _ from 'lodash';
59
60// -----
61
62var path = require('path');
63var _ = require('lodash');
64
65// -----
66
67// Allowed as ̀`babel-register` is not assigned.
68require('babel-register');
69var path = require('path');
70
71// -----
72
73// Allowed as `import` must be before `require`
74import foo from './foo';
75var path = require('path');
76```
77
78## Limitations of `--fix`
79
80Unbound imports are assumed to have side effects, and will never be moved/reordered. This can cause other imports to get "stuck" around them, and the fix to fail.
81
82```javascript
83import b from 'b'
84import 'format.css'; // This will prevent --fix from working.
85import a from 'a'
86```
87
88As a workaround, move unbound imports to be entirely above or below bound ones.
89
90```javascript
91import 'format1.css'; // OK
92import b from 'b'
93import a from 'a'
94import 'format2.css'; // OK
95```
96
97## Options
98
99This rule supports the following options (none of which are required):
100
101 - [`groups`][18]
102 - [`pathGroups`][8]
103 - [`pathGroupsExcludedImportTypes`][9]
104 - [`distinctGroup`][32]
105 - [`newlines-between`][20]
106 - [`alphabetize`][30]
107 - [`named`][33]
108 - [`warnOnUnassignedImports`][5]
109 - [`sortTypesGroup`][7]
110 - [`newlines-between-types`][27]
111 - [`consolidateIslands`][25]
112
113---
114
115### `groups`
116
117Valid values: `("builtin" | "external" | "internal" | "unknown" | "parent" | "sibling" | "index" | "object" | "type")[]` \
118Default: `["builtin", "external", "parent", "sibling", "index"]`
119
120Determines which imports are subject to ordering, and how to order
121them. The predefined groups are: `"builtin"`, `"external"`, `"internal"`,
122`"unknown"`, `"parent"`, `"sibling"`, `"index"`, `"object"`, and `"type"`.
123
124The import order enforced by this rule is the same as the order of each group
125in `groups`. Imports belonging to groups omitted from `groups` are lumped
126together at the end.
127
128#### Example
129
130```jsonc
131{
132 "import/order": ["error", {
133 "groups": [
134 // Imports of builtins are first
135 "builtin",
136 // Then sibling and parent imports. They can be mingled together
137 ["sibling", "parent"],
138 // Then index file imports
139 "index",
140 // Then any arcane TypeScript imports
141 "object",
142 // Then the omitted imports: internal, external, type, unknown
143 ],
144 }],
145}
146```
147
148#### How Imports Are Grouped
149
150An import (a `ImportDeclaration`, `TSImportEqualsDeclaration`, or `require()` `CallExpression`) is grouped by its type (`"require"` vs `"import"`), its [specifier][4], and any corresponding identifiers.
151
152```ts
153import { identifier1, identifier2 } from 'specifier1';
154import type { MyType } from 'specifier2';
155const identifier3 = require('specifier3');
156```
157
158Roughly speaking, the grouping algorithm is as follows:
159
1601. If the import has no corresponding identifiers (e.g. `import './my/thing.js'`), is otherwise "unassigned," or is an unsupported use of `require()`, and [`warnOnUnassignedImports`][5] is disabled, it will be ignored entirely since the order of these imports may be important for their [side-effects][31]
1612. If the import is part of an arcane TypeScript declaration (e.g. `import log = console.log`), it will be considered **object**. However, note that external module references (e.g. `import x = require('z')`) are treated as normal `require()`s and import-exports (e.g. `export import w = y;`) are ignored entirely
1623. If the import is [type-only][6], `"type"` is in `groups`, and [`sortTypesGroup`][7] is disabled, it will be considered **type** (with additional implications if using [`pathGroups`][8] and `"type"` is in [`pathGroupsExcludedImportTypes`][9])
1634. If the import's specifier matches [`import/internal-regex`][28], it will be considered **internal**
1645. If the import's specifier is an absolute path, it will be considered **unknown**
1656. If the import's specifier has the name of a Node.js core module (using [is-core-module][10]), it will be considered **builtin**
1667. If the import's specifier matches [`import/core-modules`][11], it will be considered **builtin**
1678. If the import's specifier is a path relative to the parent directory of its containing file (e.g. starts with `../`), it will be considered **parent**
1689. If the import's specifier is one of `['.', './', './index', './index.js']`, it will be considered **index**
16910. If the import's specifier is a path relative to its containing file (e.g. starts with `./`), it will be considered **sibling**
17011. If the import's specifier is a path pointing to a file outside the current package's root directory (determined using [package-up][12]), it will be considered **external**
17112. If the import's specifier matches [`import/external-module-folders`][29] (defaults to matching anything pointing to files within the current package's `node_modules` directory), it will be considered **external**
17213. If the import's specifier is a path pointing to a file within the current package's root directory (determined using [package-up][12]), it will be considered **internal**
17314. If the import's specifier has a name that looks like a scoped package (e.g. `@scoped/package-name`), it will be considered **external**
17415. If the import's specifier has a name that starts with a word character, it will be considered **external**
17516. If this point is reached, the import will be ignored entirely
176
177At the end of the process, if they co-exist in the same file, all top-level `require()` statements that haven't been ignored are shifted (with respect to their order) below any ES6 `import` or similar declarations. Finally, any type-only declarations are potentially reorganized according to [`sortTypesGroup`][7].
178
179### `pathGroups`
180
181Valid values: `PathGroup[]` \
182Default: `[]`
183
184Sometimes [the predefined groups][18] are not fine-grained enough, especially when using import aliases.
185`pathGroups` defines one or more [`PathGroup`][13]s relative to a predefined group.
186Imports are associated with a [`PathGroup`][13] based on path matching against the import specifier (using [minimatch][14]).
187
188> [!IMPORTANT]
189>
190> Note that, by default, imports grouped as `"builtin"`, `"external"`, or `"object"` will not be considered for further `pathGroups` matching unless they are removed from [`pathGroupsExcludedImportTypes`][9].
191
192#### `PathGroup`
193
194| property | required | type | description |
195| :--------------: | :------: | :--------------------: | ------------------------------------------------------------------------------------------------------------------------------- |
196| `pattern` | ☑️ | `string` | [Minimatch pattern][16] for specifier matching |
197| `patternOptions` | | `object` | [Minimatch options][17]; default: `{nocomment: true}` |
198| `group` | ☑️ | [predefined group][18] | One of the [predefined groups][18] to which matching imports will be positioned relatively |
199| `position` | | `"after" \| "before"` | Where, in relation to `group`, matching imports will be positioned; default: same position as `group` (neither before or after) |
200
201#### Example
202
203```jsonc
204{
205 "import/order": ["error", {
206 "pathGroups": [
207 {
208 // Minimatch pattern used to match against specifiers
209 "pattern": "~/**",
210 // The predefined group this PathGroup is defined in relation to
211 "group": "external",
212 // How matching imports will be positioned relative to "group"
213 "position": "after"
214 }
215 ]
216 }]
217}
218```
219
220### `pathGroupsExcludedImportTypes`
221
222Valid values: `("builtin" | "external" | "internal" | "unknown" | "parent" | "sibling" | "index" | "object" | "type")[]` \
223Default: `["builtin", "external", "object"]`
224
225By default, imports in certain [groups][18] are excluded from being matched against [`pathGroups`][8] to prevent overeager sorting.
226Use `pathGroupsExcludedImportTypes` to modify which groups are excluded.
227
228> [!TIP]
229>
230> If using imports with custom specifier aliases (e.g.
231> you're using `eslint-import-resolver-alias`, `paths` in `tsconfig.json`, etc) that [end up
232> grouped][3] as `"builtin"` or `"external"` imports,
233> remove them from `pathGroupsExcludedImportTypes` to ensure they are ordered
234> correctly.
235
236#### Example
237
238```jsonc
239{
240 "import/order": ["error", {
241 "pathGroups": [
242 {
243 "pattern": "@app/**",
244 "group": "external",
245 "position": "after"
246 }
247 ],
248 "pathGroupsExcludedImportTypes": ["builtin"]
249 }]
250}
251```
252
253### `distinctGroup`
254
255Valid values: `boolean` \
256Default: `true`
257
258> [!CAUTION]
259>
260> Currently, `distinctGroup` defaults to `true`. However, in a later update, the
261> default will change to `false`.
262
263This changes how [`PathGroup.position`][13] affects grouping, and is most useful when [`newlines-between`][20] is set to `always` and at least one [`PathGroup`][13] has a `position` property set.
264
265When [`newlines-between`][20] is set to `always` and an import matching a specific [`PathGroup.pattern`][13] is encountered, that import is added to a sort of "sub-group" associated with that [`PathGroup`][13]. Thanks to [`newlines-between`][20], imports in this "sub-group" will have a new line separating them from the rest of the imports in [`PathGroup.group`][13].
266
267This behavior can be undesirable when using [`PathGroup.position`][13] to order imports _within_ [`PathGroup.group`][13] instead of creating a distinct "sub-group". Set `distinctGroup` to `false` to disable the creation of these "sub-groups".
268
269#### Example
270
271```jsonc
272{
273 "import/order": ["error", {
274 "distinctGroup": false,
275 "newlines-between": "always",
276 "pathGroups": [
277 {
278 "pattern": "@app/**",
279 "group": "external",
280 "position": "after"
281 }
282 ]
283 }]
284}
285```
286
287### `newlines-between`
288
289Valid values: `"ignore" | "always" | "always-and-inside-groups" | "never"` \
290Default: `"ignore"`
291
292Enforces or forbids new lines between import groups.
293
294 - If set to `ignore`, no errors related to new lines between import groups will be reported
295
296 - If set to `always`, at least one new line between each group will be enforced, and new lines inside a group will be forbidden
297
298 > [!TIP]
299 >
300 > To prevent multiple lines between imports, the [`no-multiple-empty-lines` rule][21], or a tool like [Prettier][22], can be used.
301
302 - If set to `always-and-inside-groups`, it will act like `always` except new lines are allowed inside import groups
303
304 - If set to `never`, no new lines are allowed in the entire import section
305
306#### Example
307
308With the default [`groups`][18] setting, the following will fail the rule check:
309
310```ts
311/* eslint import/order: ["error", {"newlines-between": "always"}] */
312import fs from 'fs';
313import path from 'path';
314import sibling from './foo';
315import index from './';
316```
317
318```ts
319/* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
320import fs from 'fs';
321
322import path from 'path';
323import sibling from './foo';
324import index from './';
325```
326
327```ts
328/* eslint import/order: ["error", {"newlines-between": "never"}] */
329import fs from 'fs';
330import path from 'path';
331
332import sibling from './foo';
333
334import index from './';
335```
336
337While this will pass:
338
339```ts
340/* eslint import/order: ["error", {"newlines-between": "always"}] */
341import fs from 'fs';
342import path from 'path';
343
344import sibling from './foo';
345
346import index from './';
347```
348
349```ts
350/* eslint import/order: ["error", {"newlines-between": "always-and-inside-groups"}] */
351import fs from 'fs';
352
353import path from 'path';
354
355import sibling from './foo';
356
357import index from './';
358```
359
360```ts
361/* eslint import/order: ["error", {"newlines-between": "never"}] */
362import fs from 'fs';
363import path from 'path';
364import sibling from './foo';
365import index from './';
366```
367
368### `alphabetize`
369
370Valid values: `{ order?: "asc" | "desc" | "ignore", orderImportKind?: "asc" | "desc" | "ignore", caseInsensitive?: boolean }` \
371Default: `{ order: "ignore", orderImportKind: "ignore", caseInsensitive: false }`
372
373Determine the sort order of imports within each [predefined group][18] or [`PathGroup`][8] alphabetically based on specifier.
374
375> [!NOTE]
376>
377> Imports will be alphabetized based on their _specifiers_, not by their
378> identifiers. For example, `const a = require('z');` will come _after_ `const z = require('a');` when `alphabetize` is set to `{ order: "asc" }`.
379
380Valid properties and their values include:
381
382 - **`order`**: use `"asc"` to sort in ascending order, `"desc"` to sort in descending order, or "ignore" to prevent sorting
383
384 - **`orderImportKind`**: use `"asc"` to sort various _import kinds_, e.g. [type-only and typeof imports][6], in ascending order, `"desc"` to sort them in descending order, or "ignore" to prevent sorting
385
386 - **`caseInsensitive`**: use `true` to ignore case and `false` to consider case when sorting
387
388#### Example
389
390Given the following settings:
391
392```jsonc
393{
394 "import/order": ["error", {
395 "alphabetize": {
396 "order": "asc",
397 "caseInsensitive": true
398 }
399 }]
400}
401```
402
403This will fail the rule check:
404
405```ts
406import React, { PureComponent } from 'react';
407import aTypes from 'prop-types';
408import { compose, apply } from 'xcompose';
409import * as classnames from 'classnames';
410import blist from 'BList';
411```
412
413While this will pass:
414
415```ts
416import blist from 'BList';
417import * as classnames from 'classnames';
418import aTypes from 'prop-types';
419import React, { PureComponent } from 'react';
420import { compose, apply } from 'xcompose';
421```
422
423### `named`
424
425Valid values: `boolean | { enabled: boolean, import?: boolean, export?: boolean, require?: boolean, cjsExports?: boolean, types?: "mixed" | "types-first" | "types-last" }` \
426Default: `false`
427
428Enforce ordering of names within imports and exports.
429
430If set to `true` or `{ enabled: true }`, _all_ named imports must be ordered according to [`alphabetize`][30].
431If set to `false` or `{ enabled: false }`, named imports can occur in any order.
432
433If set to `{ enabled: true, ... }`, and any of the properties `import`, `export`, `require`, or `cjsExports` are set to `false`, named ordering is disabled with respect to the following kind of expressions:
434
435 - `import`:
436
437 ```ts
438 import { Readline } from "readline";
439 ```
440
441 - `export`:
442
443 ```ts
444 export { Readline };
445 // and
446 export { Readline } from "readline";
447 ```
448
449 - `require`:
450
451 ```ts
452 const { Readline } = require("readline");
453 ```
454
455 - `cjsExports`:
456
457 ```ts
458 module.exports.Readline = Readline;
459 // and
460 module.exports = { Readline };
461 ```
462
463Further, the `named.types` option allows you to specify the order of [import identifiers with inline type qualifiers][23] (or "type-only" identifiers/names), e.g. `import { type TypeIdentifier1, normalIdentifier2 } from 'specifier';`.
464
465`named.types` accepts the following values:
466
467 - `types-first`: forces type-only identifiers to occur first
468 - `types-last`: forces type-only identifiers to occur last
469 - `mixed`: sorts all identifiers in alphabetical order
470
471#### Example
472
473Given the following settings:
474
475```jsonc
476{
477 "import/order": ["error", {
478 "named": true,
479 "alphabetize": {
480 "order": "asc"
481 }
482 }]
483}
484```
485
486This will fail the rule check:
487
488```ts
489import { compose, apply } from 'xcompose';
490```
491
492While this will pass:
493
494```ts
495import { apply, compose } from 'xcompose';
496```
497
498### `warnOnUnassignedImports`
499
500Valid values: `boolean` \
501Default: `false`
502
503Warn when "unassigned" imports are out of order.
504Unassigned imports are imports with no corresponding identifiers (e.g. `import './my/thing.js'` or `require('./side-effects.js')`).
505
506> [!NOTE]
507>
508> These warnings are not fixable with `--fix` since unassigned imports might be used for their [side-effects][31],
509> and changing the order of such imports cannot be done safely.
510
511#### Example
512
513Given the following settings:
514
515```jsonc
516{
517 "import/order": ["error", {
518 "warnOnUnassignedImports": true
519 }]
520}
521```
522
523This will fail the rule check:
524
525```ts
526import fs from 'fs';
527import './styles.css';
528import path from 'path';
529```
530
531While this will pass:
532
533```ts
534import fs from 'fs';
535import path from 'path';
536import './styles.css';
537```
538
539### `sortTypesGroup`
540
541Valid values: `boolean` \
542Default: `false`
543
544> [!NOTE]
545>
546> This setting is only meaningful when `"type"` is included in [`groups`][18].
547
548Sort [type-only imports][6] separately from normal non-type imports.
549
550When enabled, the intragroup sort order of [type-only imports][6] will mirror the intergroup ordering of normal imports as defined by [`groups`][18], [`pathGroups`][8], etc.
551
552#### Example
553
554Given the following settings:
555
556```jsonc
557{
558 "import/order": ["error", {
559 "groups": ["type", "builtin", "parent", "sibling", "index"],
560 "alphabetize": { "order": "asc" }
561 }]
562}
563```
564
565This will fail the rule check even though it's logically ordered as we expect (builtins come before parents, parents come before siblings, siblings come before indices), the only difference is we separated type-only imports from normal imports:
566
567```ts
568import type A from "fs";
569import type B from "path";
570import type C from "../foo.js";
571import type D from "./bar.js";
572import type E from './';
573
574import a from "fs";
575import b from "path";
576import c from "../foo.js";
577import d from "./bar.js";
578import e from "./";
579```
580
581This happens because [type-only imports][6] are considered part of one global
582[`"type"` group](#how-imports-are-grouped) by default. However, if we set
583`sortTypesGroup` to `true`:
584
585```jsonc
586{
587 "import/order": ["error", {
588 "groups": ["type", "builtin", "parent", "sibling", "index"],
589 "alphabetize": { "order": "asc" },
590 "sortTypesGroup": true
591 }]
592}
593```
594
595The same example will pass.
596
597### `newlines-between-types`
598
599Valid values: `"ignore" | "always" | "always-and-inside-groups" | "never"` \
600Default: the value of [`newlines-between`][20]
601
602> [!NOTE]
603>
604> This setting is only meaningful when [`sortTypesGroup`][7] is enabled.
605
606`newlines-between-types` is functionally identical to [`newlines-between`][20] except it only enforces or forbids new lines between _[type-only][6] import groups_, which exist only when [`sortTypesGroup`][7] is enabled.
607
608In addition, when determining if a new line is enforceable or forbidden between the type-only imports and the normal imports, `newlines-between-types` takes precedence over [`newlines-between`][20].
609
610#### Example
611
612Given the following settings:
613
614```jsonc
615{
616 "import/order": ["error", {
617 "groups": ["type", "builtin", "parent", "sibling", "index"],
618 "sortTypesGroup": true,
619 "newlines-between": "always"
620 }]
621}
622```
623
624This will fail the rule check:
625
626```ts
627import type A from "fs";
628import type B from "path";
629import type C from "../foo.js";
630import type D from "./bar.js";
631import type E from './';
632
633import a from "fs";
634import b from "path";
635
636import c from "../foo.js";
637
638import d from "./bar.js";
639
640import e from "./";
641```
642
643However, if we set `newlines-between-types` to `"ignore"`:
644
645```jsonc
646{
647 "import/order": ["error", {
648 "groups": ["type", "builtin", "parent", "sibling", "index"],
649 "sortTypesGroup": true,
650 "newlines-between": "always",
651 "newlines-between-types": "ignore"
652 }]
653}
654```
655
656The same example will pass.
657
658Note the new line after `import type E from './';` but before `import a from "fs";`. This new line separates the type-only imports from the normal imports. Its existence is governed by [`newlines-between-types`][27] and _not `newlines-between`_.
659
660> [!IMPORTANT]
661>
662> In certain situations, [`consolidateIslands: true`][25] will take precedence over `newlines-between-types: "never"`, if used, when it comes to the new line separating type-only imports from normal imports.
663
664The next example will pass even though there's a new line preceding the normal import and [`newlines-between`][20] is set to `"never"`:
665
666```jsonc
667{
668 "import/order": ["error", {
669 "groups": ["type", "builtin", "parent", "sibling", "index"],
670 "sortTypesGroup": true,
671 "newlines-between": "never",
672 "newlines-between-types": "always"
673 }]
674}
675```
676
677```ts
678import type A from "fs";
679
680import type B from "path";
681
682import type C from "../foo.js";
683
684import type D from "./bar.js";
685
686import type E from './';
687
688import a from "fs";
689import b from "path";
690import c from "../foo.js";
691import d from "./bar.js";
692import e from "./";
693```
694
695While the following fails due to the new line between the last type import and the first normal import:
696
697```jsonc
698{
699 "import/order": ["error", {
700 "groups": ["type", "builtin", "parent", "sibling", "index"],
701 "sortTypesGroup": true,
702 "newlines-between": "always",
703 "newlines-between-types": "never"
704 }]
705}
706```
707
708```ts
709import type A from "fs";
710import type B from "path";
711import type C from "../foo.js";
712import type D from "./bar.js";
713import type E from './';
714
715import a from "fs";
716
717import b from "path";
718
719import c from "../foo.js";
720
721import d from "./bar.js";
722
723import e from "./";
724```
725
726### `consolidateIslands`
727
728Valid values: `"inside-groups" | "never"` \
729Default: `"never"`
730
731> [!NOTE]
732>
733> This setting is only meaningful when [`newlines-between`][20] and/or [`newlines-between-types`][27] is set to `"always-and-inside-groups"`.
734
735When set to `"inside-groups"`, this ensures imports spanning multiple lines are separated from other imports with a new line while single-line imports are grouped together (and the space between them consolidated) if they belong to the same [group][18] or [`pathGroups`][8].
736
737> [!IMPORTANT]
738>
739> When all of the following are true:
740>
741> - [`sortTypesGroup`][7] is set to `true`
742> - `consolidateIslands` is set to `"inside-groups"`
743> - [`newlines-between`][20] is set to `"always-and-inside-groups"` when [`newlines-between-types`][27] is set to `"never"` (or vice-versa)
744>
745> Then [`newlines-between`][20]/[`newlines-between-types`][27] will yield to
746> `consolidateIslands` and allow new lines to separate multi-line imports
747> regardless of the `"never"` setting.
748>
749> This configuration is useful, for instance, to keep single-line type-only
750> imports stacked tightly together at the bottom of your import block to
751> preserve space while still logically organizing normal imports for quick and
752> pleasant reference.
753
754#### Example
755
756Given the following settings:
757
758```jsonc
759{
760 "import/order": ["error", {
761 "newlines-between": "always-and-inside-groups",
762 "consolidateIslands": "inside-groups"
763 }]
764}
765```
766
767This will fail the rule check:
768
769```ts
770var fs = require('fs');
771var path = require('path');
772var { util1, util2, util3 } = require('util');
773var async = require('async');
774var relParent1 = require('../foo');
775var {
776 relParent21,
777 relParent22,
778 relParent23,
779 relParent24,
780} = require('../');
781var relParent3 = require('../bar');
782var { sibling1,
783 sibling2, sibling3 } = require('./foo');
784var sibling2 = require('./bar');
785var sibling3 = require('./foobar');
786```
787
788While this will succeed (and is what `--fix` would yield):
789
790```ts
791var fs = require('fs');
792var path = require('path');
793var { util1, util2, util3 } = require('util');
794
795var async = require('async');
796
797var relParent1 = require('../foo');
798
799var {
800 relParent21,
801 relParent22,
802 relParent23,
803 relParent24,
804} = require('../');
805
806var relParent3 = require('../bar');
807
808var { sibling1,
809 sibling2, sibling3 } = require('./foo');
810
811var sibling2 = require('./bar');
812var sibling3 = require('./foobar');
813```
814
815Note the intragroup "islands" of grouped single-line imports, as well as multi-line imports, are surrounded by new lines. At the same time, note the typical new lines separating different groups are still maintained thanks to [`newlines-between`][20].
816
817The same holds true for the next example; when given the following settings:
818
819```jsonc
820{
821 "import/order": ["error", {
822 "alphabetize": { "order": "asc" },
823 "groups": ["external", "internal", "index", "type"],
824 "pathGroups": [
825 {
826 "pattern": "dirA/**",
827 "group": "internal",
828 "position": "after"
829 },
830 {
831 "pattern": "dirB/**",
832 "group": "internal",
833 "position": "before"
834 },
835 {
836 "pattern": "dirC/**",
837 "group": "internal"
838 }
839 ],
840 "newlines-between": "always-and-inside-groups",
841 "newlines-between-types": "never",
842 "pathGroupsExcludedImportTypes": [],
843 "sortTypesGroup": true,
844 "consolidateIslands": "inside-groups"
845 }]
846}
847```
848
849> [!IMPORTANT]
850>
851> **Pay special attention to the value of [`pathGroupsExcludedImportTypes`][9]** in this example's settings.
852> Without it, the successful example below would fail.
853> This is because the imports with specifiers starting with "dirA/", "dirB/", and "dirC/" are all [considered part of the `"external"` group](#how-imports-are-grouped), and imports in that group are excluded from [`pathGroups`][8] matching by default.
854>
855> The fix is to remove `"external"` (and, in this example, the others) from [`pathGroupsExcludedImportTypes`][9].
856
857This will fail the rule check:
858
859```ts
860import c from 'Bar';
861import d from 'bar';
862import {
863 aa,
864 bb,
865 cc,
866 dd,
867 ee,
868 ff,
869 gg
870} from 'baz';
871import {
872 hh,
873 ii,
874 jj,
875 kk,
876 ll,
877 mm,
878 nn
879} from 'fizz';
880import a from 'foo';
881import b from 'dirA/bar';
882import index from './';
883import type { AA,
884 BB, CC } from 'abc';
885import type { Z } from 'fizz';
886import type {
887 A,
888 B
889} from 'foo';
890import type { C2 } from 'dirB/Bar';
891import type {
892 D2,
893 X2,
894 Y2
895} from 'dirB/bar';
896import type { E2 } from 'dirB/baz';
897import type { C3 } from 'dirC/Bar';
898import type {
899 D3,
900 X3,
901 Y3
902} from 'dirC/bar';
903import type { E3 } from 'dirC/baz';
904import type { F3 } from 'dirC/caz';
905import type { C1 } from 'dirA/Bar';
906import type {
907 D1,
908 X1,
909 Y1
910} from 'dirA/bar';
911import type { E1 } from 'dirA/baz';
912import type { F } from './index.js';
913import type { G } from './aaa.js';
914import type { H } from './bbb';
915```
916
917While this will succeed (and is what `--fix` would yield):
918
919```ts
920import c from 'Bar';
921import d from 'bar';
922
923import {
924 aa,
925 bb,
926 cc,
927 dd,
928 ee,
929 ff,
930 gg
931} from 'baz';
932
933import {
934 hh,
935 ii,
936 jj,
937 kk,
938 ll,
939 mm,
940 nn
941} from 'fizz';
942
943import a from 'foo';
944
945import b from 'dirA/bar';
946
947import index from './';
948
949import type { AA,
950 BB, CC } from 'abc';
951
952import type { Z } from 'fizz';
953
954import type {
955 A,
956 B
957} from 'foo';
958
959import type { C2 } from 'dirB/Bar';
960
961import type {
962 D2,
963 X2,
964 Y2
965} from 'dirB/bar';
966
967import type { E2 } from 'dirB/baz';
968import type { C3 } from 'dirC/Bar';
969
970import type {
971 D3,
972 X3,
973 Y3
974} from 'dirC/bar';
975
976import type { E3 } from 'dirC/baz';
977import type { F3 } from 'dirC/caz';
978import type { C1 } from 'dirA/Bar';
979
980import type {
981 D1,
982 X1,
983 Y1
984} from 'dirA/bar';
985
986import type { E1 } from 'dirA/baz';
987import type { F } from './index.js';
988import type { G } from './aaa.js';
989import type { H } from './bbb';
990```
991
992## Related
993
994 - [`import/external-module-folders`][29]
995 - [`import/internal-regex`][28]
996 - [`import/core-modules`][11]
997
998[3]: #how-imports-are-grouped
999[4]: https://nodejs.org/api/esm.html#terminology
1000[5]: #warnonunassignedimports
1001[6]: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-export
1002[7]: #sorttypesgroup
1003[8]: #pathgroups
1004[9]: #pathgroupsexcludedimporttypes
1005[10]: https://www.npmjs.com/package/is-core-module
1006[11]: ../../README.md#importcore-modules
1007[12]: https://www.npmjs.com/package/package-up
1008[13]: #pathgroup
1009[14]: https://www.npmjs.com/package/minimatch
1010[16]: https://www.npmjs.com/package/minimatch#features
1011[17]: https://www.npmjs.com/package/minimatch#options
1012[18]: #groups
1013[20]: #newlines-between
1014[21]: https://eslint.org/docs/latest/rules/no-multiple-empty-lines
1015[22]: https://prettier.io
1016[23]: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html#type-modifiers-on-import-names
1017[25]: #consolidateislands
1018[27]: #newlines-between-types
1019[28]: ../../README.md#importinternal-regex
1020[29]: ../../README.md#importexternal-module-folders
1021[30]: #alphabetize
1022[31]: https://webpack.js.org/guides/tree-shaking#mark-the-file-as-side-effect-free
1023[32]: #distinctgroup
1024[33]: #named
Note: See TracBrowser for help on using the repository browser.