Skip to content

Commit c42a081

Browse files
byaraKLewin23annesnour03chason-choate-trilliantRyderKishan
authored
V6 (#385)
* Add sort by length option * fix types * Correct default type Co-authored-by: annes <[email protected]> * Yet another <SEPARATOR> feature PR (#339) * Added current-state snapshots Capturing the current state of transformations so we can see how the upcoming changes affect them. * Add `<SEPARATOR>` support When `importOrderSeparation` is enabled, users can further control separation placement with the `<SEPARATOR>` keyword. * fix tests, update docs * feat: Import sort order skip files * Downgraded minimatch for node 18 * Added new types * (fix) Types error * Switch to ESM * Ensure all tests are running * Correctly resolve plugin * Remove some changes * Fix svelte * Require node >= 20.x (#367) * Require node >= 20.x * Add checking 24.x * docs: add pnpm install command to README (#361) * Switch to vitest for better ESM support I was still hitting issues with jest and trying to get full ESM support, so I decided to switch to vitest. This seems to be working and snapshots are generated essentially the same. * Explicitly import expect and test * Fix types * Fix accidentally checked file * Add extensions to imports, fix some example issues * Make tsc happy * Convert all cjs to mjs * Fix some things * Get examples and tests working * (fix) PR review comments analysed and reviewed * State now matches upstream/main * Revert "State now matches upstream/main" This reverts commit a7db2b5. * Fixed version mis matches * [Format] Run prettier on most files Summary: ``` $ npx prettier --write . ``` Manually inspected changes, and reverted changes to examples, package.json, and tsconfig.json Test Plan: doitlive * Delete ppsi.spec.js.snap * Delete prettier.config.mjs * Alt: Add support for gjs/gts, fix examples more (#377) * Add support for gjs/gts, fix examples more * WIP * hm * wheeeee * Revert extraneous svelte change * Revert extraneous vue change * Update src/preprocessors/ember-preprocessor.ts Co-authored-by: Robbie Wagner <[email protected]> * Update examples/.prettierrc Co-authored-by: Robbie Wagner <[email protected]> * Update .prettierrc Co-authored-by: Robbie Wagner <[email protected]> * Update examples/example.gts Co-authored-by: Robbie Wagner <[email protected]> * Update examples/example.gjs Co-authored-by: Robbie Wagner <[email protected]> * Update tests/Ember/sfc.gts Co-authored-by: Robbie Wagner <[email protected]> * Support namespace imports * Support named type imports * Fix all type imports * debugging improvement to run_spec * Fix parser * Reduce config * Extract replaceAt to its own util and add tests for it * Fix spelling: injest -> ingest --------- Co-authored-by: Robbie Wagner <[email protected]> Co-authored-by: Robbie Wagner <[email protected]> * 6.0.0-0 * [Test] Stop ignoring exceptions thrown in snapshot tests Summary: This logic can hide breakages and cause tests to pass when the underlying logic is actually broken. I encountered these hidden breakages while working on some further feature changes, and figured it was appropriate to fix this first. As all existing tests pass without the try/catch, this change is effectively a no-op. Test Plan: `yarn install && yarn run test ./tests/` * [Perf] Improve performance of removeNodesFromOriginalCode() Summary: This change replaces the existing RegExp replace() logic with concatenated string slices. This avoids reallocation the result string for each node replacement, replacing it with string slice operations (which are implemented as O(1) string views within v8) and a single .join(''), which can be optimized by the runtime to a single allocation. This probably won't make a noticable difference, but the change also simplifies some further feature work I am attempting to add. Test Plan: `yarn install && yarn run test --all` * [Refactor] Stop rerendering directives, inject imports instead Summary: This commit changes how the sorted imports are combined with the original source. Prior to this commit, all ImportDeclaration nodes and their leading comments, plus any InterpreterDirective and Directive nodes, were extracted from the original code and re-rendered using babel. The rendered nodes were then concatenated with the original source with those nodes removed to produce the updated source. This approach safely protected against functional changes, but removed newlines around comments near the beginning of the file when the first node of the original source was an ImportDeclaration, as babel does not preserve whitespace when rendering content. If a user has configured a plugin that attempts to manage comments and/or whitespace near the top of the file, such as auto-inserting a license header (as I am trying to do), this results in conflicts / formatting churn. This commit does not directly resolve this incompatibility, however it better prepares the codebase for a plugin option to be added that can resolve the issue. Test Plan: `yarn install && yarn run test --all` Note that one snapshot was changed by this commit where a newline was changed, acting as an effective example of how the original approach could affect whitespace in the re-rendered portion of the file. * [Feature] Expand detection for `sort-imports-ignore` Summary: Prior to this commit, isSortImportsIgnored() checked comments associated with the extracted ImportDirectives, and only if the comment started on line 1. This could result in a failure to suppress sorting if the comment was not next to an ImportDirective (never considered), the first import directive were embedded later in the file (line mismatch), or directives/shebangs were used (Line 1 is unavailable). With this change, the line restriction is removed, and all comments from the beginning of the file and the first statement are checked. This ensures better coverage, especially with the importOrderIgnoreHeaderComments feature stacked on this commit. Test Plan: `yarn install && yarn run test --all` * Add sortNodeBuiltinModulesToTop * Refactor: Use <BUILTIN_MODULES> placeholder instead of boolean option * Fix test file extensions to .mjs for ES modules compatibility * fix undefined error * Update Ember snapshot and clean up debug code * run yarn prettify * prettify files * remove changelog entry * update CHANGELOG with features * run yarn * Revert "run yarn" This reverts commit 5b1b267. --------- Co-authored-by: KLewin23 <[email protected]> Co-authored-by: annes <[email protected]> Co-authored-by: Chason Choate <[email protected]> Co-authored-by: RyderKishan <[email protected]> Co-authored-by: Robbie Wagner <[email protected]> Co-authored-by: Robert Wagner <[email protected]> Co-authored-by: Vladislav Arsenev <[email protected]> Co-authored-by: Nathan H. Leung <[email protected]> Co-authored-by: Balkishan <[email protected]> Co-authored-by: Cullen Walsh <[email protected]> Co-authored-by: NullVoxPopuli <[email protected]> Co-authored-by: Ayush Sharma <[email protected]> Co-authored-by: Vladislav Arsenev <[email protected]> Co-authored-by: Stuart Dotson <[email protected]>
1 parent f7b685c commit c42a081

File tree

112 files changed

+3217
-2570
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+3217
-2570
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ jobs:
55
runs-on: ubuntu-latest
66
strategy:
77
matrix:
8-
node: [18.x, 20.x, 22.x]
8+
node: [20.x, 22.x, 24.x]
99
steps:
1010
- uses: actions/checkout@v4
1111
- uses: actions/setup-node@v4

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
tests/
22
lib/
3+
examples/
4+
.github/
5+
docs/
6+
*.md

.prettierrc

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 4,
4+
"trailingComma": "all",
5+
"singleQuote": true,
6+
"bracketSameLine": true,
7+
"semi": true,
8+
"importOrder": ["^[./]"],
9+
"importOrderSeparation": true,
10+
"importOrderSortSpecifiers": true,
11+
"plugins": [
12+
"prettier-plugin-ember-template-tag",
13+
"prettier-plugin-svelte",
14+
"./lib/src/index.js"
15+
]
16+
}

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,31 @@
22

33

44
---
5+
### 6.0.0
6+
7+
#### Breaking Changes
8+
- **Switch to ESM** [#366](https://github.com/trivago/prettier-plugin-sort-imports/pull/366) by [@RobbieTheWagner](https://github.com/RobbieTheWagner) - The plugin now uses ES modules instead of CommonJS
9+
- **Require Node >= 20.x** [#367](https://github.com/trivago/prettier-plugin-sort-imports/pull/367) by [@RobbieTheWagner](https://github.com/RobbieTheWagner) - Drop support for Node.js versions below 20
10+
- **Switch to vitest** [#370](https://github.com/trivago/prettier-plugin-sort-imports/pull/370) by [@RobbieTheWagner](https://github.com/RobbieTheWagner) - Replaced Jest with Vitest for better ESM support
11+
12+
#### New features
13+
- **Ember.js gjs/gts support** [#377](https://github.com/trivago/prettier-plugin-sort-imports/pull/377) by [@NullVoxPopuli](https://github.com/NullVoxPopuli) and [@RobbieTheWagner](https://github.com/RobbieTheWagner) - Add support for Ember.js gjs/gts file formats with namespace and named type imports
14+
- **`<BUILTIN_MODULES>` placeholder** [#381](https://github.com/trivago/prettier-plugin-sort-imports/pull/381) by [@sdotson](https://github.com/sdotson) - Add support for sorting Node.js builtin modules to a specific position using `<BUILTIN_MODULES>` placeholder in `importOrder`
15+
- **`<SEPARATOR>` placeholder** [#339](https://github.com/trivago/prettier-plugin-sort-imports/pull/339) - Add `<SEPARATOR>` keyword for fine-grained control over import group separation when `importOrderSeparation` is enabled
16+
- **Sort by length option** [#224](https://github.com/trivago/prettier-plugin-sort-imports/pull/224) by [@KLewin23](https://github.com/KLewin23) - Add option to sort imports by import statement length
17+
- **`importOrderExclude` option** [#384](https://github.com/trivago/prettier-plugin-sort-imports/pull/384) by [@RyderKishan](https://github.com/RyderKishan) - Add support for excluding specific files from import sorting using glob patterns
18+
- **Expand `sort-imports-ignore` detection** [#358](https://github.com/trivago/prettier-plugin-sort-imports/pull/358) by [@ckwalsh](https://github.com/ckwalsh) - Improved detection of `sort-imports-ignore` comments throughout the file, not just at line 1
19+
20+
#### Performance improvements
21+
- **Improve `removeNodesFromOriginalCode()` performance** [#356](https://github.com/trivago/prettier-plugin-sort-imports/pull/356) by [@ckwalsh](https://github.com/ckwalsh) - Replace RegExp logic with string slices for better performance
22+
23+
#### Refactoring
24+
- **Stop rerendering directives** [#357](https://github.com/trivago/prettier-plugin-sort-imports/pull/357) by [@ckwalsh](https://github.com/ckwalsh) - Inject imports instead of re-rendering directives to better preserve whitespace and reduce formatting conflicts
25+
- **Stop ignoring exceptions in snapshot tests** [#355](https://github.com/trivago/prettier-plugin-sort-imports/pull/355) by [@ckwalsh](https://github.com/ckwalsh) - Improve test reliability by properly handling exceptions
26+
27+
#### Chores
28+
- Add pnpm install command to README [#361](https://github.com/trivago/prettier-plugin-sort-imports/pull/361) - Document pnpm installation option
29+
530
### 5.2.2
631
- Update packages and pin babel/types [#343](https://github.com/trivago/prettier-plugin-sort-imports/pull/343) by [@byara](https://github.com/byara)
732

CODE_OF_CONDUCT.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,21 @@ orientation.
1414
Examples of behavior that contributes to creating a positive environment
1515
include:
1616

17-
* Using welcoming and inclusive language
18-
* Being respectful of differing viewpoints and experiences
19-
* Gracefully accepting constructive criticism
20-
* Focusing on what is best for the community
21-
* Showing empathy towards other community members
17+
- Using welcoming and inclusive language
18+
- Being respectful of differing viewpoints and experiences
19+
- Gracefully accepting constructive criticism
20+
- Focusing on what is best for the community
21+
- Showing empathy towards other community members
2222

2323
Examples of unacceptable behavior by participants include:
2424

25-
* The use of sexualized language or imagery and unwelcome sexual attention or
26-
advances
27-
* Trolling, insulting/derogatory comments, and personal or political attacks
28-
* Public or private harassment
29-
* Publishing others' private information, such as a physical or electronic
25+
- The use of sexualized language or imagery and unwelcome sexual attention or
26+
advances
27+
- Trolling, insulting/derogatory comments, and personal or political attacks
28+
- Public or private harassment
29+
- Publishing others' private information, such as a physical or electronic
3030
address, without explicit permission
31-
* Other conduct which could reasonably be considered inappropriate in a
31+
- Other conduct which could reasonably be considered inappropriate in a
3232
professional setting
3333

3434
## Our Responsibilities
@@ -71,4 +71,4 @@ This Code of Conduct is adapted from the [Contributor Covenant][homepage], versi
7171
available at [http://contributor-covenant.org/version/1/4][version]
7272

7373
[homepage]: http://contributor-covenant.org
74-
[version]: http://contributor-covenant.org/version/1/4/
74+
[version]: http://contributor-covenant.org/version/1/4/

README.md

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import React, {
1515
KeyboardEvent,
1616
} from 'react';
1717
import { logger } from '@core/logger';
18-
import { reduce, debounce } from 'lodash';
18+
import { reduce, debounce } from 'lodash-es';
1919
import { Message } from '../Message';
2020
import { createServer } from '@server/node';
2121
import { Alert } from '@ui/Alert';
@@ -29,7 +29,7 @@ import { createConnection } from '@server/database';
2929
### Output
3030

3131
```javascript
32-
import { debounce, reduce } from 'lodash';
32+
import { debounce, reduce } from 'lodash-es';
3333
import React, {
3434
ChangeEvent,
3535
FC,
@@ -53,18 +53,24 @@ import { add, filter, repeat } from '../utils';
5353

5454
### Install
5555

56-
npm
56+
using npm
5757

5858
```shell script
5959
npm install --save-dev @trivago/prettier-plugin-sort-imports
6060
```
6161

62-
or, using yarn
62+
using yarn
6363

6464
```shell script
6565
yarn add --dev @trivago/prettier-plugin-sort-imports
6666
```
6767

68+
using pnpm
69+
70+
```shell script
71+
pnpm add -D @trivago/prettier-plugin-sort-imports
72+
```
73+
6874
**Note: If you are migrating from v2.x.x to v3.x.x, [Please Read Migration Guidelines](./docs/MIGRATION.md)**
6975

7076
**Note: If formatting `.vue` sfc files please install `@vue/compiler-sfc` if not in your dependency tree - this normally is within Vue projects.**
@@ -114,6 +120,14 @@ To move the third party imports at desired place, you can use `<THIRD_PARTY_MODU
114120
"importOrder": ["^@core/(.*)$", "<THIRD_PARTY_MODULES>", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
115121
```
116122

123+
You can also use `<BUILTIN_MODULES>` to control the position of Node.js builtin modules (like `fs`, `path`, `http`, and their `node:` prefixed variants):
124+
125+
```
126+
"importOrder": ["<BUILTIN_MODULES>", "<THIRD_PARTY_MODULES>", "^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
127+
```
128+
129+
When `<BUILTIN_MODULES>` is included in your `importOrder`, Node.js builtin modules will be sorted to that position. If not included, builtin modules are treated as regular third-party imports.
130+
117131
#### `importOrderSeparation`
118132

119133
**type**: `boolean`
@@ -127,6 +141,9 @@ between sorted import declarations group. The separation takes place according t
127141
"importOrderSeparation": true,
128142
```
129143

144+
If this option is enabled and `<SEPARATOR>` is used in the `importOrder` array, the plugin
145+
will ONLY add newlines at those locations and at the end of the imports.
146+
130147
#### `importOrderSortSpecifiers`
131148

132149
**type**: `boolean`
@@ -198,6 +215,13 @@ with options as a JSON string of the plugin array:
198215
importOrderParserPlugins: []
199216
```
200217

218+
### `importOrderSortByLength`
219+
**type**: `'asc' | 'desc' | null`
220+
**default value**: `null`
221+
222+
A choice value to enable sorting imports within their groups based on their string lengths, the two options being ascending and descending.
223+
Leaving the value blank or setting it to null will result in length being ignored
224+
201225
### `importOrderSideEffects`
202226
**type**: `boolean`
203227
**default value**: `true`
@@ -229,6 +253,7 @@ import b from 'b'
229253
import c from 'c'
230254
```
231255

256+
232257
### Ignoring import ordering
233258

234259
In some cases it's desired to ignore import ordering, specifically if you require to instantiate a common service or polyfill in your application logic before all the other imports. The plugin supports the `// sort-imports-ignore` comment, which will exclude the file from ordering the imports.
@@ -267,6 +292,12 @@ In the end, the plugin returns final imports with _third party imports_ on top a
267292

268293
The _third party imports_ position (it's top by default) can be overridden using the `<THIRD_PARTY_MODULES>` special word in the `importOrder`.
269294

295+
### Pattern Matching Implementation
296+
297+
This plugin uses [minimatch](https://github.com/isaacs/minimatch) for pattern matching of import paths. The matching is performed using the exact version specified in the plugin's dependencies to ensure consistent behavior. This is important to note because different versions of minimatch or other glob matching libraries might have subtle differences in their pattern matching behavior.
298+
299+
If you're experiencing unexpected matching behavior, please ensure you're using patterns compatible with minimatch's syntax, which might differ slightly from other glob implementations.
300+
270301
### FAQ / Troubleshooting
271302

272303
Having some trouble or an issue ? You can check [FAQ / Troubleshooting section](./docs/TROUBLESHOOTING.md).
@@ -277,11 +308,13 @@ Having some trouble or an issue ? You can check [FAQ / Troubleshooting section](
277308
| ---------------------- | ------------------------ | ------------------------------------------------ |
278309
| JS with ES Modules | ✅ Everything | - |
279310
| NodeJS with ES Modules | ✅ Everything | - |
311+
| Angular | ✅ Everything | Supported through `importOrderParserPlugins` API |
312+
| Ember | ✅ Everything | `prettier-plugin-ember-template-tag` is required |
280313
| React | ✅ Everything | - |
281314
| Solid | ✅ Everything | - |
282-
| Angular | ✅ Everything | Supported through `importOrderParserPlugins` API |
283-
| Vue | ✅ Everything | `@vue/compiler-sfc` is required |
284315
| Svelte | ✅ Everything | `prettier-plugin-svelte` is required |
316+
| Vue | ✅ Everything | `@vue/compiler-sfc` is required |
317+
285318

286319
### Used by
287320

@@ -299,10 +332,10 @@ debug some code in the plugin, check [Debugging Guidelines](./docs/DEBUG.md)
299332

300333
### Maintainers
301334

302-
| [Ayush Sharma](https://github.com/ayusharma) | [Behrang Yarahmadi](https://github.com/byara) | [Vladislav Arsenev](https://github.com/vladislavarsenev) |
303-
| ------------------------------------------------------------------------ | --------------------------------------------------------------------- |--------------------------------------------------------------------------|
304-
| ![ayusharma](https://avatars2.githubusercontent.com/u/6918450?s=120&v=4) | ![@byara](https://avatars2.githubusercontent.com/u/6979966?s=120&v=4) |![@vladislavarsenev](https://avatars.githubusercontent.com/u/51095682?s=120&v=4)|
305-
| [@ayusharma](https://twitter.com/ayusharma_) | [@behrang_y](https://twitter.com/behrang_y) | |
335+
| [Ayush Sharma](https://github.com/ayusharma) | [Behrang Yarahmadi](https://github.com/byara) |
336+
| ------------------------------------------------------------------------ | --------------------------------------------------------------------- |
337+
| ![ayusharma](https://avatars2.githubusercontent.com/u/6918450?s=120&v=4) | ![@byara](https://avatars2.githubusercontent.com/u/6979966?s=120&v=4) |
338+
| [@ayusharma\_](https://twitter.com/ayusharma_) | [@behrang_y](https://twitter.com/behrang_y) |
306339

307340
### Disclaimer
308341

docs/TROUBLESHOOTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ Due to the package handling of the pnpm, sometimes, the plugin is not automatica
8787
via prettier config.
8888
```js
8989
module.exports = {
90-
plugins: [require('@trivago/prettier-plugin-sort-imports')],
90+
plugins: ['@trivago/prettier-plugin-sort-imports'],
9191
}
9292
```
9393

examples/.prettierrc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,9 @@
88
"importOrder": ["^@server/(.*)$", "^@core/(.*)$", "^@ui/(.*)$", "^[./]"],
99
"importOrderSeparation": true,
1010
"importOrderSortSpecifiers": true,
11-
"plugins": ["../lib/src/index.js"]
11+
"plugins": [
12+
"prettier-plugin-ember-template-tag",
13+
"prettier-plugin-svelte",
14+
"../lib/src/index.js"
15+
]
1216
}

examples/example.gjs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// I am top level comment in this file.
2+
import z from 'z';
3+
import threeLevelRelativePath from '../../../threeLevelRelativePath';
4+
import sameLevelRelativePath from './sameLevelRelativePath';
5+
import thirdParty from 'third-party';
6+
import oneLevelRelativePath from '../oneLevelRelativePath';
7+
import otherthing from '@core/otherthing';
8+
import abc from '@core/abc';
9+
import twoLevelRelativePath from '../../twoLevelRelativePath';
10+
import component from '@ui/hello';
11+
import fourLevelRelativePath from '../../../../fourLevelRelativePath';
12+
import * as a from 'a';
13+
import something from '@server/something';
14+
import xyz from '@ui/xyz';
15+
import Component from '@glimmer/component';
16+
import { action } from '@ember/object';
17+
18+
const what = <template>Used as an expression</template>;
19+
20+
export const who = <template>Used as an expression</template>;
21+
22+
export default class Foo extends Component {
23+
@action
24+
myCoolFunction(){}
25+
26+
<template>
27+
Top-level class template
28+
</template>
29+
}

examples/example.gts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// I am top level comment in this file.
2+
import z from 'z';
3+
import threeLevelRelativePath from '../../../threeLevelRelativePath';
4+
import sameLevelRelativePath from './sameLevelRelativePath';
5+
import thirdParty from 'third-party';
6+
import oneLevelRelativePath from '../oneLevelRelativePath';
7+
import otherthing from '@core/otherthing';
8+
import abc from '@core/abc';
9+
import twoLevelRelativePath from '../../twoLevelRelativePath';
10+
import component from '@ui/hello';
11+
import fourLevelRelativePath from '../../../../fourLevelRelativePath';
12+
import * as a from 'a';
13+
import type RouterService from '@ember/routing/router-service';
14+
import something from '@server/something';
15+
import xyz from '@ui/xyz';
16+
import Component from '@glimmer/component';
17+
import { action } from '@ember/object';
18+
import { getOwner } from '@ember/owner';
19+
import { setOwner } from '@ember/owner';
20+
import type Owner from '@ember/owner';
21+
import type DefaultOwner from '@ember/owner';
22+
import type * as AllOwner from '@ember/owner';
23+
24+
interface FooSignature {
25+
Args: {
26+
bar: string
27+
};
28+
}
29+
30+
const what = <template>Used as an expression</template>;
31+
32+
export const who = <template>Used as an expression</template>;
33+
34+
export default class Foo extends Component<FooSignature> {
35+
@action
36+
myCoolFunction(){}
37+
38+
<template>
39+
Top-level class template
40+
</template>
41+
}

0 commit comments

Comments
 (0)