Skip to content

Commit

Permalink
Custom import order separation (#12)
Browse files Browse the repository at this point in the history
Closes #11

This is an adaptation of trivago/prettier-plugin-sort-imports#42 from @atombrenner.  I wasn't able to use most of the commits from the original branch, because our approach is different in this project, but I did pull in his commit with tests.  

The other change I needed to make here was to modify the cloned nodes in `adjustCommentsOnSortedNodes`, rather than mutating the original, which was leading to some strange bugs in the tests.  

* Add test for "local" groups, include newlines in tests

`getSortedNodesByImportOrder` includes a check for `importOrderSeparation`,
and adds newlines when it's true, so we should include that in our tests.

* Add support for custom import group separators

* add tests

* Update snapshots

But the last snapshot is wrong, will fix in next commit

* Copy nodes when adjusting comments

Mutating the original nodes causes strange effects, as seen in the snapshot

* Avoid duplicate newlines

* minor: Remove unused variables

* Update README

Co-authored-by: Christian Rodemeyer <christian.rodemeyer@sz.de>
  • Loading branch information
IanVS and Christian Rodemeyer committed May 17, 2022
1 parent 29500d4 commit b9dac83
Show file tree
Hide file tree
Showing 21 changed files with 763 additions and 125 deletions.
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,11 @@ A collection of Regular expressions in string format.
"importOrder": ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
```

_Default behavior:_ The plugin moves the third party imports to the top which are not part of the `importOrder` list.
_Default:_ `[]`

By default, this plugin will not move any imports. To separate third party from relative imports, use `["^[./]"]`. This will become the default in the next major version.

The plugin moves the third party imports to the top which are not part of the `importOrder` list.
To move the third party imports at desired place, you can use `<THIRD_PARTY_MODULES>` to assign third party imports to the appropriate position:

```json
Expand All @@ -149,6 +153,18 @@ between sorted import declarations group. The separation takes place according t
"importOrderSeparation": true,
```

_Note:_ If you want greater control over which groups are separated from others, you can add an empty string to your `importOrder` array to signify newlines. For example:

```js
"importOrderSeparation": false,
"importOrder": [
"^react", // React will be placed at the top of third-party modules
"<THIRD_PARTY_MODULES>",
"", // use empty strings to separate groups with empty lines
"^[./]"
],
```

#### `importOrderSortSpecifiers`

**type**: `boolean`
Expand Down
71 changes: 35 additions & 36 deletions src/utils/__tests__/adjust-comments-on-sorted-nodes.spec.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { ImportDeclaration } from '@babel/types';

import type { ImportOrLine } from '../../types';
import { adjustCommentsOnSortedNodes } from '../adjust-comments-on-sorted-nodes';
import { getImportNodes } from '../get-import-nodes';

function leadingComments(node: ImportDeclaration): string[] {
function leadingComments(node: ImportOrLine): string[] {
return node.leadingComments?.map((c) => c.value) ?? [];
}

function trailingComments(node: ImportDeclaration): string[] {
function trailingComments(node: ImportOrLine): string[] {
return node.trailingComments?.map((c) => c.value) ?? [];
}

Expand All @@ -21,14 +20,14 @@ test('it preserves the single leading comment for each import declaration', () =
`);
expect(importNodes).toHaveLength(3);
const finalNodes = [importNodes[2], importNodes[1], importNodes[0]];
adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(finalNodes).toHaveLength(3);
expect(leadingComments(finalNodes[0])).toEqual([' comment a']);
expect(trailingComments(finalNodes[0])).toEqual([]);
expect(leadingComments(finalNodes[1])).toEqual([' comment b']);
expect(trailingComments(finalNodes[1])).toEqual([]);
expect(leadingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(finalNodes[2])).toEqual([]);
const adjustedNodes = adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(adjustedNodes).toHaveLength(3);
expect(leadingComments(adjustedNodes[0])).toEqual([' comment a']);
expect(trailingComments(adjustedNodes[0])).toEqual([]);
expect(leadingComments(adjustedNodes[1])).toEqual([' comment b']);
expect(trailingComments(adjustedNodes[1])).toEqual([]);
expect(leadingComments(adjustedNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[2])).toEqual([]);
});

test('it preserves multiple leading comments for each import declaration', () => {
Expand All @@ -45,22 +44,22 @@ test('it preserves multiple leading comments for each import declaration', () =>
`);
expect(importNodes).toHaveLength(3);
const finalNodes = [importNodes[2], importNodes[1], importNodes[0]];
adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(finalNodes).toHaveLength(3);
expect(leadingComments(finalNodes[0])).toEqual([
const adjustedNodes = adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(adjustedNodes).toHaveLength(3);
expect(leadingComments(adjustedNodes[0])).toEqual([
' comment a1',
' comment a2',
' comment a3',
]);
expect(trailingComments(finalNodes[0])).toEqual([]);
expect(leadingComments(finalNodes[1])).toEqual([
expect(trailingComments(adjustedNodes[0])).toEqual([]);
expect(leadingComments(adjustedNodes[1])).toEqual([
' comment b1',
' comment b2',
' comment b3',
]);
expect(trailingComments(finalNodes[1])).toEqual([]);
expect(leadingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[1])).toEqual([]);
expect(leadingComments(adjustedNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[2])).toEqual([]);
});

test('it does not move comments at before all import declarations', () => {
Expand All @@ -73,17 +72,17 @@ test('it does not move comments at before all import declarations', () => {
`);
expect(importNodes).toHaveLength(3);
const finalNodes = [importNodes[2], importNodes[1], importNodes[0]];
adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(finalNodes).toHaveLength(3);
expect(leadingComments(finalNodes[0])).toEqual([
const adjustedNodes = adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(adjustedNodes).toHaveLength(3);
expect(leadingComments(adjustedNodes[0])).toEqual([
' comment c1',
' comment c2',
]);
expect(trailingComments(finalNodes[0])).toEqual([]);
expect(leadingComments(finalNodes[1])).toEqual([]);
expect(trailingComments(finalNodes[1])).toEqual([]);
expect(leadingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[0])).toEqual([]);
expect(leadingComments(adjustedNodes[1])).toEqual([]);
expect(trailingComments(adjustedNodes[1])).toEqual([]);
expect(leadingComments(adjustedNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[2])).toEqual([]);
});

test('it does not affect comments after all import declarations', () => {
Expand All @@ -96,12 +95,12 @@ test('it does not affect comments after all import declarations', () => {
`);
expect(importNodes).toHaveLength(3);
const finalNodes = [importNodes[2], importNodes[1], importNodes[0]];
adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(finalNodes).toHaveLength(3);
expect(leadingComments(finalNodes[0])).toEqual([]);
expect(trailingComments(finalNodes[0])).toEqual([]);
expect(leadingComments(finalNodes[1])).toEqual([]);
expect(trailingComments(finalNodes[1])).toEqual([]);
expect(leadingComments(finalNodes[2])).toEqual([]);
expect(trailingComments(finalNodes[2])).toEqual([]);
const adjustedNodes = adjustCommentsOnSortedNodes(importNodes, finalNodes);
expect(adjustedNodes).toHaveLength(3);
expect(leadingComments(adjustedNodes[0])).toEqual([]);
expect(trailingComments(adjustedNodes[0])).toEqual([]);
expect(leadingComments(adjustedNodes[1])).toEqual([]);
expect(trailingComments(adjustedNodes[1])).toEqual([]);
expect(leadingComments(adjustedNodes[2])).toEqual([]);
expect(trailingComments(adjustedNodes[2])).toEqual([]);
});

0 comments on commit b9dac83

Please sign in to comment.