-
-
Notifications
You must be signed in to change notification settings - Fork 780
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
feat(extractor-arbitrary-variants)!: make arbitrary extractor standalone #2364
Conversation
✅ Deploy Preview for unocss ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
test/assets/preset-mini-targets.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need these tests. They are not tested against extractors because of being provided as an array. They are only tested against rules and variants.
We should concat presetMiniTargets
and presetArbitraryTargets
in tests, and also join them into a string to be sure generated CSS is the same as the array.
test/assets/preset-wind-targets.ts
Outdated
@@ -394,7 +394,6 @@ export const presetWindTargets: string[] = [ | |||
|
|||
// variants experimental | |||
'@hover-text-red', | |||
'@hover:[[open]_&]:text-blue', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add a separate test for this in preset-wind.test.ts
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been moved to
unocss/test/assets/preset-arbitrary-target.ts
Lines 16 to 17 in 350fd1a
// variants experimental | |
'@hover:[[open]_&]:text-blue', |
code | ||
.split(defaultSplitRE) | ||
.forEach((match) => { | ||
if (isValidSelector(match) && !arbitraryPropertyCandidateRE.test(match)) | ||
result.add(match) | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably will not work as it was working previously in split.ts
. The purpose of these lines is to reduce some false positives captured by defaultSplitRE
. We remove those false positives on line 12.
If I remember correctly, this is capturing false positives like that:
hover="[&>span]:text-white"
Which is excluded from the tests currently.
split.ts
will capture [&>span]:text-white
and presetAttributify will capture hover="[&>span]:text-white"
and unocss will generate unused [&>span]:text-white
.
If this is a thing, we can't merge this PR without resolving this regression.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should provide code
variable as a MagicString instance and remove the matched utilities from the code. That means this extractor should run before the default splitter (split.ts).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another solution is would be removing the default splitter from the extractors list since this extractor already does its job. This is not an ideal solution and we don't have access to uno config on here as of now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To me, it's actually fine as a little redundant in UnoCSS is invertible, we the rules merge it shouldn't have much impact.
Meanwhile, when not using preset-arbitrary
, it shouldn't generate such rule. While if using preset-arbitrary
with atrributify, it replaces the default split
function, which makes it identical to the previous behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a "preprocessor" for extractors is a great idea and I have been thinking it for a while as well. As currently the pug and svelte extractor are coupled with the default extractor.
I will see how we can do it in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have some benchmarking tests to see performance cost before/after?
While actual performance is not my concern here. What I am concerned about is the "agnostic" part. The core should not be aware of how the utils are defined in presets, and split.ts should provide a minimal and transparent implementation for the possibility of other presets to use. |
Ran |
Recently added configResolved almost no-op when not using unocss/packages/core/src/config.ts Lines 59 to 62 in 8554bf4
And this already meets the "agnostic" part. So, instead of moving arbitrary extractor to a separate package, we should move it to preset-mini. This way, the core extractor can stay agnostic, and our preset can still process the possible candidates that they already target.
My test results: (windi, tailwind disabled, 50x) main branch:
feat/preset-arbitrary branch:
feat/preset-arbitrary is 5.34459% faster. OK, there are some performance wins here. But I don't think it's worth introducing a breaking change. Since performance is not a main concern here instead of introducing a breaking change, we should make it customizable as part of the presets, and people who don't need it can disable it. And the core extractor will stay agnostic. I see no point in moving this extractor to a separate package and making it default disabled by default. Continuing the above discussion here:
Merging rules will only work if we used those false positives in class attribute. IMO even on a big size project, this is very unlikely to happen. And the real issue is not even that. The real issue is those false positives are highlighted on VS Code. pos.test.ts still have false positives. My guess is that you need to update
I was thinking of more unified pre/post processor API. IMO we should deprecate all preprocess/postprocess/configResolved options and have a hook option with a bunch of hooks that can take control on generating process, e.g.
|
test/pos.test.ts
Outdated
46, | ||
65, | ||
"[&>span]:text-white", | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in my last comment, this shouldn't be here.
test/pos.test.ts
Outdated
[ | ||
13, | ||
14, | ||
"b", | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I mentioned in my last comment, this shouldn't be here.
variants: [ | ||
variantVariables, | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO variantVariables
should stay in its original place in preset-mini and this package should be renamed to @unocss/extractor-arbitrary like #2368.
variantVariables has preset-mini specific code and has nothing to do with extracting. Otherwise we have to move cssProperty rule here too and having preset-mini dependency in an extractor package doesn't make sense:
unocss/packages/preset-mini/src/_rules/variables.ts
Lines 28 to 33 in 8554bf4
export const cssProperty: Rule[] = [ | |
[/^\[(--(\w|\\\W)+|[\w-]+):([^\s:]*?("\S+?"|'\S+?'|`\S+?`|[^\s:]+?)[^\s:]*?\)?)\]$/, ([match, prop,, value]) => { | |
if (!isURI(match.slice(1, -1))) | |
return { [prop]: h.bracket(`[${value}]`) } | |
}], | |
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And by doing that we can include arbitrary extractor in preset-mini exctractors and avoid breaking change.
That sounds good to me. Initially, I was thinking of enabling arbitrary variants also for other presets. Directly embedding could also do.
That's probably not a bad idea. But I think we won't implement all hooks you mentioned at once. Instead, we could implement them when we see the needs, so we don't over-engineer. |
While at it, I think the variants on preset-mini may benefit when split on separate package |
I feel the current arbitrary variant support is a bit polluting the core too much. Ideally, the core should be agnostic. Also, I think arbitrary variants might not be needed for everyone, so making it a separate PR so ppl could opt-in when needed, and ppl don't use it do not need to pay the performance cost.
/cc @chu121su12 @sibbng let me know what you think, thanks!