-
Notifications
You must be signed in to change notification settings - Fork 71
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improper order of imports with Hyphens and Periods in the paths #87
Comments
Hi! I think this happens due to the way I implemented directory structure sorting: eslint-plugin-simple-import-sort/src/shared.js Lines 802 to 826 in 7aa4e22
Personally I have no idea which order punctuation is “usually” sorted in so I would never have noticed something like this myself. I have one question: Does it matter to you that |
Thanks for responding and sharing the code where the problem might lie, @lydell. I will try to analyze each of the regular expressions and determine which code line might be causing this switch.
Yes, it is one of those opinionated things, but apparently, it matters to me and our team. I am just trying ensure that my code changes are as minimally invasive as possible to all files within the current Angular 11 repository. The Angular 11 repository that I am working on is at-least 6+ years in the making. It started off as an AngularJS (Angular v1) application and has been steadily kept up to date with the latest - 1 version of Angular - while adding more and more functionality around the core code. It is hosted on a private GitHub repository and contains the code for a publicly available website. Lot of the original developers who wrote the original code have left - and the tribal knowledge about many parts of the website code is lost with them - no comments, no documentation, etc. However, they did implement strict We also have a strict 3 reviewer policy on our PRs. Longer PRs (especially these conversion PRs with 1000+ file changes) take longer turn around time to get reviews. At the moment I am dealing with this import order problem - because it's swapping out the hyphen and period import statements in around 300+ files. It was flagged by one of our senior developers and the PR wouldn't be approved until I fix this problem. Ameet |
It’s the one with the eslint-plugin-simple-import-sort/src/shared.js Lines 812 to 826 in 7aa4e22
Have you looked into using a For me personally, I don’t care about git history for
Note that tslint compatibility is not a goal of this plugin. I created this plugin before I even used TypeScript. I think your next steps are:
|
@lydell - I think I have found the root cause of this problem. But I don't know why it happens. Posting my analysis here shortly. |
Analysis so far@lydell - From your
When comparing hyphens and forward-slashes using the vanilla JavaScript comparator (without passing thru the ES Internationalization Collator API), I see that forward slashes are /: // Vanilla JS comparator
const cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
cmp('/', '_');
// Output: -1
// Indicating ascending sort order of ['/', `_`]
// Reversing your `switch` statement logic yields ['-', '.']
// This is GOOD for my use-case However, when passing thru new Intl.Collator('en', { sensitivity: 'base', numeric: true }).compare('/', '_');
// Output: 1
// Indicating ascending sort order ['_', '/']
// Reversing your `switch` statement logic yields ['.', '-']
// This is BAD for my use-case Need to find out why the |
Yes, I noticed vanilla JS comparator and Intl.Collator sorted differently last time I fiddled with this too. What I did last time was to generate a list with all ASCII characters and sort them to learn what order they end up in. I saved the start of the sorted list of ASCII punctuation in this comment:
|
@lydell - Thanks for confirming my suspicions. It feels like this is a bug in the implementation of the When comparing period ( // Vanilla JS comparator
const cmp = (a, b) => a < b ? -1 : a > b ? 1 : 0;
cmp('.', '-');
// Output: 1
new Intl.Collator('en', { sensitivity: 'base', numeric: true }).compare('.', '-');
// Output: 1 |
@lydell - So, I asked this question on Stack Overflow - and I got one explanation. https://stackoverflow.com/questions/69405786/why-does-javascript-intl-collator-prototype-compare-method-yield-different-r His explanation seems sound to me for real characters - however, he could not explain why the comparison differs specifically for A couple of questions / thoughts on my mind:
|
|
Is it just me? Or are unit tests already failing in the C:\dev\lydell\eslint-plugin-simple-import-sort>npm test
> @ pretest C:\dev\lydell\eslint-plugin-simple-import-sort
> prettier --check . && eslint . --report-unused-disable-directives
Checking formatting...
[warn] .eslintrc.js
[warn] .github\workflows\check.yml
[warn] .github\workflows\test.yml
[warn] .prettierrc.json
[warn] build.js
[warn] CHANGELOG.md
[warn] jest.config.js
[warn] package-lock.json
[warn] package-real.json
[warn] package.json
[warn] README.md
[warn] src\exports.js
[warn] src\imports.js
[warn] src\index.js
[warn] src\shared.js
[warn] test\examples.test.js
[warn] test\exports.test.js
[warn] test\helpers.js
[warn] test\imports.test.js
[warn] Code style issues found in the above file(s). Forgot to run Prettier?
npm ERR! Test failed. See above for more details. |
They pass for me. And in CI. |
But it seems like you use Windows. I don’t. My guess is that your git setup has changed the newlines in all the files to CRLF, while Prettier wants just LF. |
You are correct, @lydell. I cloned your repo on my Windows 10 machine.
For now, let me try to change the line endings from CRLF to LF manually and run the unit tests on your repo. |
@lydell - I was finally able to run the unit tests on your repo. All passed.
Side Note: I was also able to figure out the line-endings LF -> CRLF problem. Apparently, there is a bug in the GitHub Desktop software where it ignores the system level settings (bug details - desktop/desktop#10666). I had to set the git config --global core.autocrlf input And then re-clone your repo. All files show line endings as LF now. |
@lydell - I think I understand your requirement a bit better now after looking at the sorting expectations outlined between lines 880 and 992 - why you wanted to sort eslint-plugin-simple-import-sort/test/imports.test.js Lines 880 to 928 in 7aa4e22
|
@lydell - The deeper I follow the rabbit hole, the more I come to realize the following (sorry, if I repeated myself - trying to collect my thoughts together and document it clearly for myself here):
|
As mentioned in my comment on your PR (#91 (comment)) this is not trivial to “fix.” But in my opinion there’s nothing to fix. Punctuation don’t have a natural order. The order just is what it is. Most people don’t notice. It seems like you have a very specific situation, so I think you’d be better off using a custom solution to your problem. I’m updating the readme in #93. |
Hi @lydell,
Kudos
We are trying to convert an Angular 10 application from the deprecated
tsLint
dependency to usingeslint
. There were strong recommendations to use thiseslint
plugin. And I agree with the recommendations - your extensive research is well documented with every reasoning and finding there is to know about sortingimport
statements within Javascript / TypeScript files. Good work!Issue
However, there is one thing bothering me while using this plugin. In my opinion, your plugin seems to incorrectly sort
import
statements which have the same set of characters from the beginning of the "from
path string" followed by:-
a.k.a. the hyphen-minus unicode characterU+002D
).
a.k.a the full-stop unicode characterU+002E
).Example
from
path strings'my-package'
vs'my.package'
(Common part ='my
)'./widget/abc-def.tsx'
vs'./widget/abc.defgh.tsx'
(Common part ='./widget/abc
)'../notification-list-routing.module.ts'
vs'../notification-list.component.ts'
(Common part ='../notification-list
)According to normal string sorting, hyphens come before periods. However, the default configuration of this plugin, seems to sort the
from
path strings containing periods first followed by the hyphen character.Example
The following import sequence seems to be correct in my opinion (as well as TSLint's
ordered-import
rule).is auto-fixed into:
Sample Repository
To demonstrate this issue clearly, I have created a small sample plain-vanilla JavaScript-based NodeJS 14.x compatible application here: https://github.com/akaustav/import-order-test. The
index.js
file disables your plugin rule on line 1 - otherwise thesimple-import-sort/imports
rule keeps complaining about the order of the import lines on line 2 and 3. It even uses your documented comparator function - see this file.Question
Is this expected behavior?
Ameet
The text was updated successfully, but these errors were encountered: