Closed ADTC closed 6 months ago
Can you give an example of imports that you'd like to sort using this approach?
@IanVS hey, so this is just trying to make it easier to do "negative lookup" by extracting that out of regex and making it part of the plugin's processing logic instead.
Assume:
import D from '/app/D.css';
import E from '/app/E';
import C from '/app/C.css';
import A from '/app/A';
import B from '/app/B';
A normal sort would sort it as:
import A from '/app/A';
import B from '/app/B';
import C from '/app/C.css';
import D from '/app/D.css';
import E from '/app/E';
A sort using "negative lookup" to filter the CSS:
"importOrder": ["<THIRD_PARTY_MODULES>", "^(?!.*[.]css$)[./].*$", "", ".css$"]
... would sort it as:
import A from '/app/A';
import B from '/app/B';
import E from '/app/E';
import C from '/app/C.css';
import D from '/app/D.css';
My proposal is being able to do the same thing above using a simpler pattern that uses a special word:
"importOrder": ["<THIRD_PARTY_MODULES>", "^[.]<UNMATCH>.css$", "", ".css$"]
// '------------------'
Sorting it as:
import A from '/app/A';
import B from '/app/B';
import E from '/app/E';
import C from '/app/C.css';
import D from '/app/D.css';
The way it works is to split the string on <UNMATCH>
(there may be multiple instances):
array = "^[.]<UNMATCH>.css$".split("<UNMATCH>")
// gives:
array = ["^[.]", ".css$"]
Use array[0]
to match the superset first:
import A from '/app/A';
import B from '/app/B';
import C from '/app/C.css';
import D from '/app/D.css';
import E from '/app/E';
Use array[1] ... array[n]
to remove subset matches from the superset. What's removed is added back into the queue of imports that are still pending any matches.
import A from '/app/A';
import B from '/app/B';
import E from '/app/E';
Then it's just normal processing, continuing with ""
:
import A from '/app/A';
import B from '/app/B';
import E from '/app/E';
// <-- blank line
And with ".css$"
:
import A from '/app/A';
import B from '/app/B';
import E from '/app/E';
import C from '/app/C.css';
import D from '/app/D.css';
This makes it easier to write logic similar to "negative lookup" without the convoluted regex. It's much simpler to write "^[.]<UNMATCH>.css$"
. I can simply say "Match this superset first, but remove (unmatch) these subsets and add them back to the queue for the upcoming regex directives."
Just my 2¢: I'm uncomfortable making a dialect of regex.
Supporting this in the code (long term) could be complicated/messy/a pain -- indeed the other special words are annoying enough.
Making a dialect of regex to patch a wart in regex feels like out of bounds for this tool, and would break regex sandboxes.
Thanks for taking the time to open the issue and clearly describe what you're looking for here, @ADTC. I really appreciate hearing ideas and the reasoning behind them. And in fact, I use a similar regex exclusion to group my CSS modules at the bottom, which we document in the readme as the second example.
I'm afraid I agree with @fbartho here. Maintaining a project like this is a delicate balance between adding options and features that people want and keeping things simple and easy to maintain. In this case, what you're asking for is something that can be achieved using the tools we provide currently (regex) and while I agree that regex can be a bit complex and difficult to read, it's at least something that is well documented, flexible, and powerful. We also do our best to give multiple examples for common scenarios for those who may not be as well-versed in regex intricacies.
So, again, thanks for taking the time to open the issue, but we're not willing to make this change to the project. Please do feel free to bring up any other ideas you may have, though!
Obligatory regex comic:
Is your feature request related to a problem? The negative lookup regex pattern is incredibly complex to read and understand. Regexr.com helps but still.
Describe the solution you'd like A special keyword called
UNMATCH
which inverts the match automatically (by discounting the matches and taking what's left instead).Explanation: Group 2 would first match
^[.]
but then grab what matches.css$
and add it back into the queue of unsorted imports, so that Group 3 can match them later.Note: Group 2 and Group 3 can be anywhere in the array, not necessarily next to each other, but Group 2 must come first. However, even if you accidentally put Group 3 first there's nothing to worry about because the "unmatch" would simply produce zero results.
The key advantages here are:
<UNMATCH>
is an easy regex that simply matches a superset of imports which includes those which we will unmatch later.<UNMATCH>
and the regex in Group 3 are exactly the same. I can simply copy-paste the same regex in both, and I don't have to struggle with writing a "negative lookup" regex pattern.Tip: We could potentially have multiple
<UNMATCH>
to keep excluding multiple subsets and putting them back into the queue of unsorted imports:I don't even know how to begin to write the above in "negative lookup" regex. You'd have to be some kind of Regex God to do it. 😆
Describe alternatives you've considered The alternative is of course the negative lookup:
It's just a convoluted messy regex that must be carefully maintained to match and negative match the same set of files in two different groups.