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

feat: support HTML/Vue/Angular #5259

Merged
merged 182 commits into from Nov 4, 2018

Conversation

Projects
None yet
@ikatyang
Member

ikatyang commented Oct 13, 2018

Fixes #1882
Fixes #2097
Fixes #3767
Fixes #4095
Fixes #5098
Fixes #5263


Try out this PR:

yarn add ikatyang/prettier#feat/html/todos

# *.html defaults to `--parser html`
yarn prettier filename.html

# *.component.html defaults to `--parser angular`
yarn prettier filename.component.html

# *.vue defaults to `--parser vue`
yarn prettier filename.vue

# NOTE: framework-specific formatting won't be triggered in `--parser html`

or preview playground (hard reload to ensure it's the latest one).

Please note that syntax errors produced by child language in the playground is a known issue, it won't happen if you use it locally (i.e., prettier something.html).


Already supported on master:

  • HTML: support front matter
  • HTML: whitespace-sensitive formatting
    • support magic comment (<!-- display: block -->)
    • --html-whitespace-sensitivity <css|strict|ignore>
      • magic comments take precedence
      • (default) css: respect default css style (safe in the most cases)
      • strict: every element is considered whitespace sensitive (the safest)
      • ignore: every element is considered whitespace insensitive (dangerous)
  • HTML: support IE conditional comment (<!--[if IE]><![endif]-->)

Added in this PR:

  • HTML: support pragma (<!-- @prettier -->)
  • JS: support lit-html (html`<div>Hello ${name}!</div>`)
  • HTML: support CDATA (<![CDATA[ content ]]>)
  • HTML: support interpolation ({{jsExpression}})
  • HTML: format vue binding syntax as js expression (:class, v-if, v-bind:id, @click)
  • HTML: format angular binding syntax as js expression (*ngIf, [target], (target), [(target)])
  • JS: support angular inline template (@Component({ template: `<div>Hello World</div>` }))
  • HTML: disable custom self-closing tag recognition
  • Vue: replace with HTML parser + enable custom self-closing tag recognition

TODOs:

  • HTML: format <script type="module"> (#3767)
  • HTML: format <script type="text/markdown"> (#4095)
  • HTML: no unexpected output for style content (#5259 (comment))
  • HTML: allow tagging HTML templates with comment (#5259 (comment))
  • HTML: move framework-specific formatting to --parser <vue|angular>
    • *.vue defaults to vue parser
    • *.component.html defaults to angular parser
    • the rest *.html defaults to html parser
  • Vue: support v-for (#5259 (comment))
  • Vue: support js statements for v-on:click, @click (#5259 (comment))
  • Vue: support slot-scope (#5259 (comment))
  • Angular: support Angular-specific syntax (#5259 (comment))
    • Angular action for (target)="input"
    • Angular binding for [target]="input"
    • Angular interpolation for {{input}}
    • Angular template bindings for *directive="input"
  • HTML: fix "Comments are discarded from binding attributes" (#5263)
  • (let me know if I missed something)
    • (please report issues separately so that we can easily hide resolved comments)

  • I’ve added tests to confirm my change works.
  • (If changing the API or CLI) I’ve documented the changes I’ve made (in the docs/ directory)
  • I’ve read the contributing guidelines.

@ikatyang ikatyang referenced this pull request Oct 13, 2018

Closed

HTML TODOs #5098

17 of 26 tasks complete

This was referenced Oct 13, 2018

@Dassderdie

This comment was marked as resolved.

Dassderdie commented Oct 13, 2018

You did a great job so far! I'm really looking forward to use prettier with html too.

I just had a quick look at the angular support and noticed that *ngFor produces a Syntax Error.
example

@ikatyang

This comment was marked as resolved.

Member

ikatyang commented Oct 13, 2018

@Dassderdie Is there a reference for *ngFor syntax? It doesn't look like regular js expression. If it's differ from JS too much, we'll probably just ignore it for now. (Syntax errors for child language will be ignored if you're using Prettier locally.)

@michaeljota

This comment has been minimized.

michaeljota commented Nov 4, 2018

Thanks @ikatyang!

@ruchern

This comment has been minimized.

ruchern commented Nov 5, 2018

Thanks, @ikatyang. I am glad to be using Vue with the awesome people behind the team.

@kissu

This comment has been minimized.

kissu commented Nov 7, 2018

Was waiting so long for that, thanks @ikatyang ! 💪🏻 🎉

@homerjam

This comment was marked as resolved.

homerjam commented Nov 7, 2018

Excellent work on this, liking prettier more and more. Am I missing something or is there an issue when using <template lang="pug"> in a .vue file? 🤔

@evilebottnawi

This comment was marked as resolved.

Member

evilebottnawi commented Nov 7, 2018

@homerjam pug is not supported

@kissu

This comment was marked as resolved.

kissu commented Nov 7, 2018

@homerjam if I'm not mistaken, it's only the formatting of html in .vue Components, not Jade/Pug. It's another story. 😸

Pug may seems easier but in fact, there are more edge cases than in regular html files IMO.

@michaeljota

This comment was marked as resolved.

michaeljota commented Nov 7, 2018

@homerjam This PR adds support for HTML only.

@homerjam

This comment was marked as resolved.

homerjam commented Nov 7, 2018

Thanks for the quick answers! In case it's useful here's what I'm now doing to prevent my pug getting jumbled (per the docs):

<!-- prettier-ignore -->
<template lang="pug">
...
</template>
@evilebottnawi

This comment was marked as resolved.

Member

evilebottnawi commented Nov 7, 2018

@homerjam without <!-- prettier-ignore --> it is break code? If yes please create issue

@michaeljota

This comment has been minimized.

michaeljota commented Nov 7, 2018

@ikatyang Sorry for bother you, but I would like to confirm this behavior before I open an issue for this. I'm formatting my teams project, and came with some awkward behavior.

With --html-whitespace-sensitivity=ignore this output is produced.
Link

With --html-whitespace-sensitivity=css this output is produced.
Link

Notice that when is set to ignore, the colon is moved to a new line, while when set to css, is not. Does this is an actual issue or this is working as you would expect? I would certainly not expect for ignore to add a new line after this.

@suchipi

This comment has been minimized.

Member

suchipi commented Nov 8, 2018

@michaeljota that looks like a bug to me, could you open an issue for it?

@ikatyang

This comment has been minimized.

Member

ikatyang commented Nov 8, 2018

Opened #5396 to address the sensitivity issue between interpolation and text.

@michaeljota

This comment has been minimized.

michaeljota commented Nov 8, 2018

Thanks @ikatyang!

@erisman20

This comment has been minimized.

erisman20 commented Nov 8, 2018

This is awesome work!

One issue I am having is when I use arrow functions for handling events in Vue.

<custom-component @click="() => { console.log('clicked') }" />

Prettier adds a semi colon after the curly brace which throws an unexpected token error when building.

@michaeljota

This comment has been minimized.

michaeljota commented Nov 8, 2018

@erisman20 Can you provide a link to Prettier playground reproducing the issue?

@kissu

This comment has been minimized.

kissu commented Nov 8, 2018

@erisman20 can't you use <custom-component @click="console.log('clicked')" /> in that case ?
I don't see the point of an arrow function here.

For more complicated/longer functions, write down the method inside of the @click listener.

@michaeljota

This comment has been minimized.

michaeljota commented Nov 8, 2018

@kissu I don't much know about vue, but I'll guess this is about the this context. Although seems an unusual behavior, Prettier should not break the code. And I can't reproduce the issue, Prettier indeed adds a semi colon, but after the function, so it shouldn't break anything.

@erisman20

This comment has been minimized.

erisman20 commented Nov 8, 2018

@kissu That was just a basic example to showcase what was happening.

Here is a Playground.

I have never used that before, but the "second format" is how prettier formats my code.

@michaeljota In terms of Vue, you cant have a trailing semi colon like that. It will throw an error. You can even try it in the provided playground and you can see the error

@lydell

This comment has been minimized.

Collaborator

lydell commented Nov 8, 2018

@erisman20 I opened an issue for you: #5406

@alfaproject

This comment has been minimized.

alfaproject commented Nov 8, 2018

Why add a semicolon in the first place? That adds an extra character for no reason o.o

@michaeljota

This comment has been minimized.

michaeljota commented Nov 8, 2018

@alfaproject That's configurable, the default behavior however is to add a semicolon at the end of a line.

@gogakoreli

This comment has been minimized.

gogakoreli commented Nov 12, 2018

Can I find out why html wrap attributes are now enforced? I am using prettier for my html files inside Angular project. This happened after I updated prettier

@duailibe

This comment has been minimized.

Member

duailibe commented Nov 12, 2018

@gogakoreli Please open an issue filling the template

@prettier prettier locked as resolved and limited conversation to collaborators Nov 12, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.