From 7180682bfca5f416ae2b96fd2e2d60bb3b844dc1 Mon Sep 17 00:00:00 2001 From: KazariEX Date: Wed, 17 Jun 2026 10:40:38 +0800 Subject: [PATCH 1/6] feat: in-tag comments --- active-rfcs/0045-in-tag-comments.md | 304 ++++++++++++++++++++++++++++ 1 file changed, 304 insertions(+) create mode 100644 active-rfcs/0045-in-tag-comments.md diff --git a/active-rfcs/0045-in-tag-comments.md b/active-rfcs/0045-in-tag-comments.md new file mode 100644 index 00000000..56a0b126 --- /dev/null +++ b/active-rfcs/0045-in-tag-comments.md @@ -0,0 +1,304 @@ +- Start Date: 2026-06-17 +- Target Major Version: 3.x +- Reference Issues: N/A +- Implementation PR: + +# Summary + +Allow HTML comments to appear inside Vue opening tag attribute lists in the same +syntactic positions as attributes. This enables line-level tooling directives, +such as `@vue-expect-error`, to be placed next to the specific attribute or +directive they apply to. + +These comments are compile-time-only. They are represented in the template AST +alongside attributes and directives, so tooling can inspect and preserve them, +but they do not become runtime comments and do not alter attribute order or +merging semantics. + +# Basic example + +```html + + :selected-id="selectedId" +/> +``` + +For generated code, this is equivalent to: + +```html + +``` + +# Motivation + +The main motivation is precise suppression and expectation of template +diagnostics. Vue's type-checking and language tooling can report errors on +individual attributes and directives inside a multi-line component tag, but +authors currently have no legal comment position that sits next to the specific +attribute or directive that is expected to error. Today, the closest legal +placement is outside the tag: + +```html + + +``` + +That placement is element-level rather than line-level: it does not clearly bind +to the `:selected-id` attribute, and it becomes less precise as the tag gains +more props, listeners, `v-model` bindings, and ARIA attributes. Placing a +JavaScript comment inside the directive expression only comments the expression +value rather than the surrounding template attribute. + +The same syntax can document groups of attributes on a large component tag, but +that is a secondary benefit. The primary goal is enabling line-level tooling +directives in multi-line tags. + +The current parser behavior is also surprising. In Vue 3.5, a template like: + +```html +
id="x">
+``` + +is not treated as a comment. The opening tag ends at the `>` in `-->`, so the +compiler sees attributes named ``, and appears while the Vue template tokenizer is +parsing an opening tag's attribute list. + +In-tag comments are allowed: + +- after the tag name and before the first attribute, with or without whitespace + after the tag name; +- between complete attributes or directives; +- after the last attribute and before `>` or `/>`. + +For example, `>` is valid and is parsed as a `div` element with +an in-tag comment before the tag closes. The comment marks the end of the tag +name and is not part of the tag name. + +The comment is represented as a distinct AST node in `ElementNode.props`, not in +`ElementNode.children`. It should record comment content and source location, +and it should be distinguishable from both child comment nodes and prop nodes. +The exact enum name is an implementation detail, but `ElementNode.props` should +be widened from `AttributeNode | DirectiveNode` to include an in-tag comment +node shape, for example `InTagCommentNode`. + +This also means the existing `comments` parser option does not affect in-tag +comments. That option controls whether normal child comments are retained as +comment nodes. In-tag comments are always retained in the AST because they are +part of the element's source-level attribute list, but they do not produce +codegen behavior. Transforms that inspect props must explicitly check the node +kind and decide how to handle in-tag comments. + +Tooling can interpret the comment content. For example, Vue language tools can +treat an in-tag `@vue-expect-error` immediately before an attribute or directive +as applying to that following prop entry. The compiler's responsibility is to +preserve the node and source order; diagnostic semantics belong to AST +consumers. + +## Attribute semantics + +Comments do not affect the existing order-dependent semantics for attributes. +Semantic passes that depend on prop order should explicitly distinguish in-tag +comment nodes from attributes and directives, and apply order-dependent +semantics only to attributes and directives. For example: + +```html +
+ class="primary" +/> +``` + +is equivalent to: + +```html +
+``` + +Duplicate attribute checks also continue to work across comments, so +`
id="b" />` emits the same diagnostic as +`
`. + +## Invalid positions + +In-tag comments are only valid between complete attributes. They are not valid +inside attribute names, directive names, directive arguments, modifiers, or +attribute values. + +The following remain invalid or are parsed according to the existing error +paths: + +```html +
ass="x" /> +
]="value" /> +
+
="a" /> +
> +``` + +Comment-like text inside quoted attribute values remains ordinary attribute text. + +## Template modes + +This proposal applies to source strings parsed by Vue's template compiler, such +as SFC templates, inline string templates, and tooling paths that feed source +into `@vue/compiler-dom` or `@vue/compiler-core`. + +It does not apply to in-DOM templates because browsers do not preserve comments +inside an opening tag's attribute list. SFC block opening tags such as +`