Skip to content

[New] Add vue/attribute-order #209

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

Merged
merged 2 commits into from
Feb 21, 2018
Merged

Conversation

erindepew
Copy link
Contributor

resolves #170

@michalsnik michalsnik changed the title vue/attribute-order [New] Add vue/attribute-order Dec 2, 2017
@michalsnik
Copy link
Member

Hey @erindepew Are you willing to work on this further on? If yes - let us know and please see last comments in #209 for more informations about possible solutions :)

@erindepew
Copy link
Contributor Author

@michalsnik sure! I was just waiting for the community to decide if they want a configuration option and if so what it should be. Are you referring to #170 (comment) ?

@michalsnik
Copy link
Member

michalsnik commented Jan 1, 2018

Cool! Sort of, but you know what? Let's start with a simple implementation that does job well according to the official style guide, that is: let's pre-define groups of attributes and only allow people to change order of those groups in configuration, but not individual attributes.
Let's not overthink it just yet.

So the default configuration could look just like this:

'vue/attributes-order': [2, {
  order: [
    'CONDITIONALS',
    'RENDER_MODIFIERS'
    // ...
  ],
}]

Groups should obviously reflect situation from style guide.

After it's done we can iterate and add custom groups support / think about possible edge scenarios etc. WDYT?

@erindepew
Copy link
Contributor Author

@michalsnik I'm going to assume that it makes sense to push off ordering them alphabetically within those groups for a future iteration?

@erindepew erindepew force-pushed the attribute-order branch 3 times, most recently from 4a71322 to c4112b5 Compare January 5, 2018 19:40
@erindepew
Copy link
Contributor Author

@michalsnik updated, let me know what you think!

Copy link
Member

@michalsnik michalsnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @erindepew for your work :) I added some comments.
@chrisvfritz could you please also take a look from a broader perspective?

:+1: Examples of **correct** code with custom order`:

```html
<!-- options: [{ order: ['LIST_RENDERING', 'CONDITIONALS', 'RENDER_MODIFIERS', 'GLOBAL', 'UNIQUE', 'BINDING', 'OTHER_ATTR', 'EVENTS', 'CONTENT', 'DEFINITION'] }] -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should use eslint-ready format here, so it's not confusing for users:

<!-- 'vue/attribute-order': [2, { order: [...] }] -->

@@ -0,0 +1,93 @@
# enforce ordering of attributes (attribute-order)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go with attributes-order


## :book: Rule Details

This rule aims to enfore ordering of component attributes. The default order is specified in the [Vue styleguide](https://vuejs.org/v2/style-guide/#Element-attribute-order-recommended).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could add default order here as a simple list:

- LIST_RENDERING
- CONDITIONALS
...and so on

and then link to official styleguide for more informations. But users should be able to quickly pick up what's going on by just looking at rule documentation :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we could even give examples for each category, what attributes does it expect actually. I think it would be a huge help!

function getPosition (attribute, attributeOrder) {
const name = attribute.key.name
if (name === 'is') {
return attributeOrder.indexOf('DEFINITION')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you could add function getAttributeType that would return DEFINITION, LIST_RENDERING and so on.

Then you could shorthen this function to:

const attributeType = getAttributeType(attribute.key.name)
return attributeOrder.indexOf(attributeType)

This way you'd eliminate multiple attributeOrder.indexOf duplication and make it even more readable :) WDYT?

module.exports = {
meta: {
docs: {
description: 'enforce ordering of attributes',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about: enforce order of attributes?


return utils.defineTemplateBodyVisitor(context, {
'VStartTag' () {
currentPosition = -1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically you should also reset previousNode here, though it won't throw error now, because of the fact that previousNode is used after it's redefined in previous conditions of VAttribute

})
tester.run('attribute-order', rule, {

valid: [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add some cases with shorthanded bindings

context.report({
node: node.key,
loc: node.loc,
message: `Attribute ${currentNode} must go before ${prevNode}.`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add " around attributes. Also I'm thinking whether the message shouldn't be more gentle and say should instead of must

} else if (name === 'model') {
return attributeOrder.indexOf('BINDING')
} else if (name === 'on') {
return attributeOrder.indexOf('EVENTS')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it catch both v-on and @?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup! I'm using @click in my tests and it seems to work fine, I'll also add v-on just to be sure

} else if (name === 'ref' || name === 'key' || name === 'slot') {
return attributeOrder.indexOf('UNIQUE')
} else if (name === 'model') {
return attributeOrder.indexOf('BINDING')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v-bind:something and :something should also be marked as binding I think, not only v-model.
Also what if someone adds property model="asd"? I think it would mark it as binding and not OTHER_ATTR. You should probably check if attribute.directive is true in all cases where you want to detect v- attribute.

README.md Outdated
@@ -161,7 +161,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
| | [require-prop-types](./docs/rules/require-prop-types.md) | require type definitions in props |
| :wrench: | [v-bind-style](./docs/rules/v-bind-style.md) | enforce `v-bind` directive style |
| :wrench: | [v-on-style](./docs/rules/v-on-style.md) | enforce `v-on` directive style |

| :wrench: | [attribute-order](./docs/rules/attribute-order.md) | enforce ordering of attributes |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you add it by hand? I see there is fixable set to null in rule, but I also see 🔧 here. Please run npm run update if you want to update readme or rule documentation header base on rule source.

@michalsnik michalsnik self-assigned this Jan 6, 2018
@michalsnik michalsnik added this to the v4.2.0 milestone Jan 6, 2018
@erindepew
Copy link
Contributor Author

@michalsnik yup, that all makes sense. Updated!

@michalsnik
Copy link
Member

Hey @erindepew, I'll take a closer look and test run soon :) So far it's looking very promising 🚀

A little advice for the future though: please try not to rebase during review, as people that check your code after review once again can't see actual changes you performed in order to resolve given suggestions. Rebasing is good right before requesting review or after review :)

@michalsnik michalsnik removed this from the v4.2.0 milestone Jan 28, 2018
- UNIQUE
ex: 'ref', 'key', 'slot'
- BINDING
ex: 'v-model', 'v-bind'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does :something="" count here too?

- OTHER_ATTR
ex: 'customProp="foo"'
- EVENTS
ex: '@click="functionCall"'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does v-on="" count here too?

is="header"
v-for="item in items"
v-if="!visible"
v-once id="uniqueID"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why there are two attributes in the same line here?

},
{
filename: 'test.vue',
code: '<template><div is="header" v-for="item in items" v-if="!visible" v-once id="uniqueID" ref="header" v-model="headerData" myProp="prop" @click="functionCall" v-text="textContent"></div></template>'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should wrap those lines so it's easier to read :)

Copy link
Contributor

@chrisvfritz chrisvfritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this Erin! I just saw one more thing to update from my perspective. 🙂

docs: {
description: 'enforce order of attributes',
category: undefined,
recommended: false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can go in the recommended category and we can remove recommended: false, since we no longer use that property.

@erindepew
Copy link
Contributor Author

Thanks @chrisvfritz and @michalsnik for the review! I made the suggested changes

Copy link
Contributor

@chrisvfritz chrisvfritz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@wadetandy
Copy link

This looks great! Would love to get this merged so our team can start taking advantage of it. Anything still outstanding here?

Copy link
Member

@michalsnik michalsnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's give it a spin! :D

@michalsnik michalsnik merged commit abbde6f into vuejs:master Feb 21, 2018
@mikesherov
Copy link

Congrats @erindepew!

@skjnldsv
Copy link

Hey! Thanks for this awesome rule @erindepew !

There was a discussion and some comments about making alphabetical order within groups, is this implemented? The documentation does not state anything related 🤔
Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule Proposal vue/attribute-order
7 participants