Please describe what the rule should do:
This rule warns about the order of the script, template & style tags.
What category of rule is this? (place an "X" next to just one item)
[x] Enforces code style
[ ] Warns about a potential error
[ ] Suggests an alternate way of doing something
[ ] Other (please specify:)
Provide 2-3 code examples that this rule will warn about:
vue/component-tags-order: ["warning", order: [ "script", "template", "style" ] ];
<template></template>
<script></script>
<style></style>
However, the following should be considered fine:
<script></script>
<template></template>
<style></style>
Thank you for this proposal!
Sounds good to me.
Additionally, we should consider about custom blocks.
We'll have to discuss the best default for this. I think template, script, style is the most common, because it's what we usually demonstrate in the docs currently, but I've been somewhat recently convinced that script, template, style makes more sense, because:
script is probably the least likely tag to be missingscript defines the interface for the component, which is probably the most referred-to informationscript when adding new classes to the template and styleI'll ping some other contributors for their thoughts here.
@chrisvfritz This make sense.
@chrisvfritz We switched to script, template, style a while back at my company for the reasons you mentionned
In my experience template is the least likely tag to be missing, then script, then style
If I don't need a template tag it's because I'm writing a more advanced component that doesn't have style and prefer to write a js or jsx file
I've written components with no script, only HTML but I've never written components with no template and a style
Some small thoughts on this enforcement. While consistency is a really good thing, there are some conditions that not one rule suits for every use case and component.
Consider when a component has a LOT of styles. Every time we need to check the relation between VM and template we need to either fold style tag or scroll a LOT to the end of the file to see the js part.
The same as previous, when there are LOTS of js logic. Adding any simple style needs LOTS of scrolling between template and style parts.
Personally, I use a rule of the thumb that count/estimate lines of the code for each section in component and put the longest part to the end so the code is more READABLE. Suggestion for this rule proposal:
@pi0 This is considerably more complicated, and does not respond to the initial demand. Why not, but I think it should be added later as an option for this rule.
I would like to have a rule like this. Is there anything I can do to help this to completion?
@mario-d-s You'd be welcome to develop it! I'm thinking that for now though, this rule would remain uncategorized and therefore would have no default. Eventually, I'd probably like to make sure this rule supports autofix, then add it to the style guide under recommended with the default of script, template, style.
The only thing holding me back is that we've mostly encouraged template, script, style up until now and it does take people some getting used to for _relatively_ little benefit if code folding is used.
Actually, we _could_ add it to recommended right now as long as this kind of ordering was supported (and the default): [['script', 'template'], 'style']. That would mean script and template must come first, but in any order, then style must be after both of those.
@chrisvfritz I'd be happy to give it a shot. Your suggestion about "optional" ordering looks good.
Do note that I have zero experience writing ESLint rules so this will probably take me some time.
Unfortunately it's not possible to implement at this moment @mario-d-s The vue-eslint-parser returns an original AST with an extra templateBody property that contain AST describing Vue template. But we don't know anything about style tag.
Could we perhaps get the following AST @mysticatea?
{
type: 'Program'
body: [
{
type: 'VElement',
name: 'template',
children: [
{
type: 'VText",
...
}
]
},
{
type: 'VElement',
name: 'script',
children: [
{
type: 'VariableDeclaration',
declaration: { ... }
},
{
type: 'ExportDefaultDeclaration',
declaration: { ... }
}
]
},
{
type: 'VElement',
name: 'style',
children: null
}
]
}
It would make things easier, and maybe we wouldn't even need an extra template body visitor (though it's just my lucky guess).
edit: Now that I think about it I can imagine other plugins and rules might've already use selector that this kind of AST might break (e.g.
Program > ExportDefaultDeclaration), so we probably can't change it with 100% certainty.
Alternatively we might add an extra field next to templateBody with informations about top-level tags - it would most likely be backwards compatible change. We already have access to the root AST from HTML Parser so it should be pretty straightforward to implement in vue-eslint-parser.
Looking once again at templateBody got me thinking 馃Do you remember @mysticatea what was the reason behind assigning result.ast.templateBody = templateBody instead of straight result.ast.templateRoot = rootAST? Looks like it might just be the solution - it would also allow us to report too many lines between tags and warn about using not scoped styles later on.
I'm happy to help and hear your thoughts @mysticatea
Most helpful comment
We'll have to discuss the best default for this. I think
template,script,styleis the most common, because it's what we usually demonstrate in the docs currently, but I've been somewhat recently convinced thatscript,template,stylemakes more sense, because:scriptis probably the least likely tag to be missingscriptdefines the interface for the component, which is probably the most referred-to informationscriptwhen adding new classes to thetemplateandstyleI'll ping some other contributors for their thoughts here.