future-architect / eslint-plugin-vue-scoped-css

ESLint plugin for Scoped CSS in Vue.js
https://future-architect.github.io/eslint-plugin-vue-scoped-css/
MIT License
98 stars 10 forks source link

`no-deprecated-deep-combinator` should fix with `:deep()` #365

Closed baffalop closed 2 months ago

baffalop commented 2 months ago

I came to this package for this rule, which is very useful to prepare a codebase for Vue 3 migration. However, the fix behaviour is a bit unexpected.

Currently with eslint --fix the rule no-deprecated-deep-combinator will replace uses of >>> with ::v-deep, ie. the following...

.child >>> .deep-child {
  /* ... */
}

...becomes

.child ::v-deep .deep-child {
  /* ... */
}

I would like it to fix to:

.child :deep(.deep-child) {
  /* ... */
}

:deep() is the only documented deep selector, and is the recommendation given by the compiler itself when the warning is emitted:

 [@vue/compiler-sfc] the >>> and /deep/ combinators have been deprecated. Use :deep() instead.

I can't figure out whether ::v-deep is just an undocumented alias or is itself due to be deprecated, but I think the fact that all documentation points to :deep() is a reason to prefer it.

I think fixing with :deep() should at least be offered as a configuration option for the rule, though preferably it should be the default. I appreciate that this would be a slightly more complex fix than ::v-deep, since it's not a straightforward replacement, but rather the brackets have to wrap the remainder of the selector.

ota-meshi commented 2 months ago

I think adding two rules will enable what you want to do.

https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/require-v-deep-argument.html https://future-architect.github.io/eslint-plugin-vue-scoped-css/rules/v-deep-pseudo-style.html

baffalop commented 2 months ago

@ota-meshi Thank you for the advice. I just tried it and I must say I'm not entirely satisfied by this solution since it doesn't change the fix behaviour, it just means the unwanted style of the fixes is caught by further rules. That is, after running eslint --fix I end up with selectors of the form .child ::v-deep .deep-child and linting errors saying "need to pass argument to ::v-deep". Apparently require-v-deep-argument cannot fix this, despite what the docs claim. (Note I am on v. 2.8.1)

Is there anywhere explaining the choice of ::v-deep as the default across the package?

ota-meshi commented 2 months ago

I don't know why the autofix doesn't work in your environment, it works fine in the online DEMO. https://future-architect.github.io/eslint-plugin-vue-scoped-css/playground/#eJyrVkrOT0lVslKyKS6pzElVKE7OL0hNsYvJ00vOyMxJUbCzs1PQS0lNLdCF8Ktj8hQU9LUU9PT0FLT0Y/JqY/Js9MFagXqUagEI6Blo

image
baffalop commented 2 months ago

Oh interesting, I'll need to experiment... Does rule order matter? 🤔