prettier icon indicating copy to clipboard operation
prettier copied to clipboard

Use void tags for supported elements rather than self-closing

Open 43081j opened this issue 9 months ago • 12 comments

As i'm sure you're aware, there's an ancient (and forever ongoing) issue around customising whether we include the / in self closing tags or not.

I'm creating this issue to be a bit more explicit and structured around the proposed solution.


Summary

Given the following definitions:

  • "self close" means <foo />
  • "void" means <foo>

The TLDR is basically:

  • All void elements should render void
  • All vue components should self-close (default of vue's lint rule which checks for this, so im guessing the vue community already leans that way)
  • All JSX components should self-close

Implementation

JSX

First of all, we can ignore JSX as it has its own printer code which already deals with self-closing tags.

HTML

That leaves us with the following requirements of the HTML printer:

  • If the element is one of the known void elements, always print it void
  • If the element is a vue component, always print it self-closing
  • In all other cases, always print the closing tag entirely (<div></div> is valid, <div /> is not)

Roughly, the places we would need to update are as follows:

  • printClosingTagEndMarker L100
    • this should be updated to return /> only if we're closing a "component" (vue)
    • all other cases should fall through to >
  • printAttributes
    • L219
    • L289
    • L293
    • this should be updated to return " " only if we're in a "component" (vue)
    • all other cases should return ""
  • angular - unknown
    • somewhere, angular embedded HTML seems to follow a different codepath which still results in " " being added, im not too sure where that lives but it too would need updating with the same logic as above

Open questions

Should we render components (vue) differently to non-void elements?

We could vastly simplify this implementation by always rendering vue components with closing tags.

For example, <Foo /> would always be printed <Foo></Foo>.

In that case, we could change our requirements to the following:

  • If the element is one of the known void elements, always print it void
  • In all other cases, always print a closing tag

How do you migrate towards this?

Obviously we can't just do this and hope all is well. This'd fundamentally change formatting of many, many projects.

So some kind of migration plan would be needed. I'm not entirely sure how that'd look yet.

Notes (IMPORTANT)

This is not an issue for us to debate whether we should include the / or not.

If the prettier team is against printing void tags, this issue and the related issue from 2018 should be closed.

This issue is specifically to spec out and define how we can solve this problem, so someone can hopefully contribute the code from the definition/requirements here.

43081j avatar Aug 30 '23 17:08 43081j