prettier/website/blog/2018-11-07-1.15.0.md

48 KiB
Raw Blame History

author authorURL title
Ika (@ikatyang) https://github.com/ikatyang Prettier 1.15: HTML, Vue, Angular and MDX Support

This release adds support for HTML, Vue, Angular and MDX. It also respects decorator position, adds an option for JSX single quotes, allows parser inference via shebang, adds support for several new syntax features, and has a few formatting tweaks.

Highlights

HTML/Vue/Angular

Support HTML, Vue, and Angular (#5259 by @ikatyang, #4753 by @evilebottnawi, #2083 by @azz)

Prettier can now format HTML, Vue and Angular files! 🎉

We use angular-html-parser, an HTML parser extracted from Angular, to parse these HTML and HTML template files so it should be highly compliant with the HTML spec thanks to the Angular team.

A few highlights:

Whitespace-sensitive formatting

As you may notice during daily HTML works, the following two cases won't produce the same output:

html output
with spaces 1<b> 2 </b>3 1 2 3
without spaces 1<b>2</b>3 123

This is because whitespaces are sensitive in inline elements.

For this reason, we cannot safely format

<a href="https://prettier.io/">Prettier is an opinionated code formatter.</a>

into

<a href="https://prettier.io/">
  Prettier is an opinionated code formatter.
</a>

since it may modify the displayed output in the browser.

Instead of breaking your code or just doing nothing, we introduce whitespace-sensitive formatting, which:

  • follows the default CSS display value for every element to identify if the whitespace is sensitive,
  • and borrows the opening or closing tags (if necessary) to avoid adding or removing sensitive whitespaces.

For example:

<!-- <span> is an inline element, <div> is a block element -->

<!-- input -->
<span class="dolorum atque aspernatur">Est molestiae sunt facilis qui rem.</span>
<div class="voluptatem architecto at">Architecto rerum architecto incidunt sint.</div>

<!-- output -->
<span class="dolorum atque aspernatur"
  >Est molestiae sunt facilis qui rem.</span
>
<div class="voluptatem architecto at">
  Architecto rerum architecto incidunt sint.
</div>

We also allow magic comments (e.g., <!-- display: block -->) to tell Prettier how to format this element due to the fact that CSS display can be changed:

<!-- input -->
<!-- display: block -->
<span class="dolorum atque aspernatur">Est molestiae sunt facilis qui rem.</span>

<!-- output -->
<!-- display: block -->
<span class="dolorum atque aspernatur">
  Est molestiae sunt facilis qui rem.
</span>

There's also an option for the global whitespace sensitivity in case you may want maximum safety or you just don't care about those whitespaces:

--html-whitespace-sensitivity (defaults to css)

  • css - Respect the default value of CSS display property.
  • strict - Whitespaces are considered sensitive.
  • ignore - Whitespaces are considered insensitive.
Automatic parser inference

Prettier uses filename to infer which parser to use. Here's the default patterns for HTML, Vue, and Angular:

  • *.html: --parser html
  • *.component.html: --parser angular
  • *.vue: --parser vue

Make sure your filename matches the correct parser (especially for Angular users); if it does not, you will have to manually specify which parser to use via the overrides field.

Note that framework-specific formatting won't be triggered in --parser html.

HTML template literal in JavaScript

This release also adds support for the html template tag (or a “tag” comment containing HTML):

  • html`code`
  • /* HTML */ `code`
// input
const foo = html`<div class="voluptatem architecto at">Architecto rerum ${interpolation} architecto incidunt sint.</div>`;

// output
const foo = html`
  <div class="voluptatem architecto at">
    Architecto rerum ${interpolation} architecto incidunt sint.
  </div>
`;
Vue formatting

The following Vue-specific syntax structures are supported:

  • interpolation
    • {{ something }}
  • attribute
    • v-something
    • :something
    • @something
    • v-for
    • slot-scope
Angular formatting

The following Angular-specific syntax structures are supported:

  • interpolation
    • {{ something }}
  • attribute
    • (something)
    • [something]
    • [(something)]
    • *something
  • inline template
    • @Component({ template: `<div>Hello World</div>` })

MDX

Support MDX (#4975 by @ikatyang)

MDX is a markdown extension that lets you use JSX to build cool documentation. You can now use Prettier to format it, and well format both the Markdown and JS pieces for you!

<!-- Input -->

import { 
  colors } from 
   './theme'
import     Palette from     './components/palette'

#      Colors

<Palette colors={
      colors} 
  />

<!-- Output -->

import { colors } from "./theme";
import Palette from "./components/palette";

# Colors

<Palette colors={colors} />

JavaScript

Flatten else-branch for nested ternaries (#5039 by @suchipi, #5272 by @duailibe, #5333 by @ikatyang)

Previously, nested ternaries were always indented, which caused increasing levels of indentation for deeply-nested ternaries. To solve this problem, we flattened the else-branch for nested ternaries in a fashion similar to how if..else if..else blocks are formatted.

// Input
const example1 =
    someValue === 'a' ? 'hello world, branch a'
  : someValue === 'b' ? 'hello world, branch a && b'
  : someValue === 'c' ? 'hello world, branch a && b && c'
  : someValue === 'd' ? 'hello world, branch a && b && c && d'
  : null;

const example2 =
  someValue === 'a'
    ? someValue === 'b'
      ? someValue === 'c'
        ? 'hello world, branch a && b && c'
        : 'hello world, branch a && b && !c'
      : 'hello world, branch a && !b' 
    : null;

// Output (Prettier 1.14)
const example1 =
  someValue === "a"
    ? "hello world, branch a"
    : someValue === "b"
      ? "hello world, branch a && b"
      : someValue === "c"
        ? "hello world, branch a && b && c"
        : someValue === "d"
          ? "hello world, branch a && b && c && d"
          : null;

const example2 =
  someValue === "a"
    ? someValue === "b"
      ? someValue === "c"
        ? "hello world, branch a && b && c"
        : "hello world, branch a && b && !c"
      : "hello world, branch a && !b"
    : null;

// Output (Prettier 1.15)
const example1 =
  someValue === "a"
    ? "hello world, branch a"
    : someValue === "b"
    ? "hello world, branch a && b"
    : someValue === "c"
    ? "hello world, branch a && b && c"
    : someValue === "d"
    ? "hello world, branch a && b && c && d"
    : null;

const example2 =
  someValue === "a"
    ? someValue === "b"
      ? someValue === "c"
        ? "hello world, branch a && b && c"
        : "hello world, branch a && b && !c"
      : "hello world, branch a && !b"
    : null;

Keep decorators inline if they were written inline (#5188 by @duailibe)

Prior to Prettier 1.14, we were always placing decorators on the same line as what they were decorating.

We received feedback from some users that this was not ideal formatting, so after consideration, we changed it and in Prettier 1.14, decorators were always placed on a separate line from what they were decorating.

However, we received feedback from other users that this formatting was not ideal in all cases.

We want to have consistent formatting in Prettier when we can, so we tried to think of a heuristic that we could use to decide when to put decorators on the same line and when to put them on another line.

However, after a long discussion in #4924, we concluded that there's no reliable way to identify which should be inlined and which shouldn't be, so in Prettier 1.15 we decided to respect the original style that the user wrote. So if they put a newline between the decorator and what it decorates, we will print a newline there. If they didn't, we won't.

// Input
class Hello {
  @decorator inline = 'value';

  @decorator
  ownLine = 'value';
  
  @decorator({
    hello: 'world'
  }) multiLine = 'value';
}

// Output (Prettier 1.14)
class Hello {
  @decorator
  inline = "value";

  @decorator
  ownLine = "value";

  @decorator({
    hello: "world"
  })
  multiLine = "value";
}

// Output (Prettier 1.15)
class Hello {
  @decorator inline = "value";

  @decorator
  ownLine = "value";

  @decorator({
    hello: "world"
  })
  multiLine = "value";
}

Respect original decorator order (#5207 by @duailibe)

Decorators are still not part of the official ECMA standard and where decorators on exported classes should go is a question whose answer has not yet been decided. To help proposal authors to get feedback, Babel 7 added support for both decorators before and after the exported classes. Prettier 1.15 adds support for them and respects where you put the decorator(s). (Once the spec is standardized, we'll change it to be consistent and not respect user input.)

// decorator before export
@decorator export class Bar {}

// decorator after export
export @decorator class Foo {}

Improved object-break heuristic (#5205 by @j-f1)

Previously, Prettier would automatically break objects onto multiple lines if they didnt fit within the print width. Prettier would also keep objects broken onto multiple lines if there was a newline somewhere inside them in the input code. This made it difficult to collapse an object since you had to manually merge the object onto one line. Since manual formatting changes are a task Prettier aims to eliminate, weve changed the behavior to only check for a newline between the { and the first key:

// Input
const data = {  foo: 'bar',
  baz: 'quux'
}
/* Youd get this format by deleting the newline after the `{` */

// Output (Prettier 1.14)
const data = {
  foo: 'bar',
  baz: 'quux'
}

// Output (Prettier 1.15)
const data = { foo: 'bar', baz: 'quux' }

JSX

Option to use single quotes in JSX (#4798 by @smirea)

After huge demand from the community, Prettier 1.15 adds an option for printing single quotes in JSX: --jsx-single-quote (or jsxSingleQuote in the config/API).

// with --jsx-single-quote
<div class='hello'>world</div>

// without --jsx-single-quote
<div class="hello">world</div>

Split JSX text correctly (#5006 by @yuliaHope)

Prettier 1.14 accidentally introduced some very unfortunate line breaks in JSX. Those cases have now been fixed.

// Input
<div>
  Sales tax estimated using a rate of {salesTax * 100}%.
</div>;
<BasicText light>(avg. {value}/5)</BasicText>;
<Link to={orgURL(this.props.org.name)}>
  Go to {this.props.org.name}'s profile
</Link>;

// Output (Prettier 1.14)
<div>
  Sales tax estimated using a rate of {salesTax * 100}
  %.
</div>;
<BasicText light>
  (avg. {value}
  /5)
</BasicText>;
<Link to={orgURL(this.props.org.name)}>
  Go to {this.props.org.name}
  's profile
</Link>;

// Output (Prettier 1.15)
<div>Sales tax estimated using a rate of {salesTax * 100}%.</div>;
<BasicText light>(avg. {value}/5)</BasicText>;
<Link to={orgURL(this.props.org.name)}>
  Go to {this.props.org.name}'s profile
</Link>;

Flow

Support inexact (#5304 by @jbrown215, #5356 by @existentialism)

The Flow team plans to treat all object types as exact by default in the future, so they introduced a new syntax to indicate if an object type is inexact. This syntax is now supported in Prettier 1.15.

type T = {
  a: number,
  ...
}

Do not break Flow typecast comments (#5280, #5290 by @swac)

Previously, parentheses that surrounds Flow typecast comments were sometimes removed, which would break Flow's comment syntax. This issue has been fixed in Prettier 1.15.

// Input
(obj /*: Class */).property

// Output (Prettier 1.14)
obj /*: Class */.property;

// Output (Prettier 1.15)
(obj /*: Class */).property;

Markdown

Preserve math syntax (#5050, #5220 by @ikatyang)

Previously, some of remark-math's syntax structures were mangled since we treated them as normal text. They are now preserved in Prettier 1.15 so you can safely use math syntax.

$inline-math$

$$
block-math
$$

Other changes

API/CLI

Infer parser via shebang if there's no extension in the filename (#5149 by @haggholm)

Previously, we used filename and extension to infer which parser to use, but often there's no extension for CLI scripts, so the user has to specify the parser manually, which is not ideal. In Prettier 1.15, when formatting a file with no extension, we'll look at the first line of the file, and if there's a shebang, we'll use it to infer which parser to use.

# Input
$ cat bin/example
\#!/usr/bin/env node
  require ( "../src/cli" ) . run ( )

$ prettier bin/example

# Output (Prettier 1.14)
[error] No parser could be inferred for file: bin/example

# Output (Prettier 1.15)
#!/usr/bin/env node
require("../src/cli").run();

Add a new trim command to trim whitespaces in the current line (#4772 by @warrenseine)

Previously in the plugin API, there was no method to delete the current lines indentation. It's possible to use some workarounds to achieve the same goal, but there wasn't a reliable workaround, so we introduced a new trim command to trim whitespaces in a reliable way.

Colorful validation message (#5020, #5057 by @ikatyang)

Previously, there was no color for the option validation error message, so it wasnt easy to see what option had an invalid value passed to it, and what the valid values were. In Prettier 1.15, you should be able to understand what's going on at a glance.

# Input
$ prettier filename.js --trailing-comma wow

# Output (Prettier 1.14)
[error] Invalid \`\`--trailing-comma\`\` value. Expected "all", "es5" or "none", but received \`"wow"\`.

# Output (Prettier 1.15)
[error] Invalid --trailing-comma value. Expected "all", "es5" or "none", but received "wow".

Allow printer to preprocess the AST (#5041 by @ikatyang)

Sometimes we need to transform the AST to make it easier to print. Previously, it was done in the parser but this way it also exposed the internal stuff to external users, who may have tried to build a custom parser, which is not ideal. In Prettier 1.15, you can now use printer.preprocess to preprocess the AST without exposing any internals of the API.

interface Printer {
  preprocess(ast: AST, options: object): AST;
}

Better error message for unsupported config format (#4969 by @ikatyang)

Previously, loading a config file of an unsupported format would throw an error message that looks like a bug in Prettier, so we improved the message in Prettier 1.15.

# Input
$ prettier filename.js --config .prettierrc.wow

# Output (Prettier 1.14)
[error] Invalid configuration file: Cannot read property 'sync' of undefined

# Output (Prettier 1.15)
[error] Invalid configuration file: No sync loader specified for extension ".wow"

Add an option to enforce line endings (#5327 by @kachkaev)

Previously, Prettier always respected your original line endings, which is fine in the most cases. But when people collaborate on a project from different operating systems, it becomes easy to end up with mixed line endings in the central git repository and cause large diffs. Prettier 1.15 adds an option --end-of-line <auto|lf|crlf|cr> to help you deal with these line ending issues.

JavaScript

Treat single-star comments as JSDoc (#5206 by @j-f1, #5330 by @lydell)

Prettier will now properly indent JSDoc-style comments with only a single * on the first line (/* vs /**) when the comments indentation changes:

// Input
if (true) {
    /*
     * Oh no
     */
}

// Output (Prettier 1.14)
if (true) {
  /*
   	 * Oh no
 	   */
}

// Output (Prettier 1.15)
if (true) {
  /*
 	 * Oh no
 	 */
}

Correct parentheses for mixed exponentiation/modulo (#5243 by @bakkot)

Previously, parentheses for mixed exponentiation/modulo were wrongly removed, but we fixed this in Prettier 1.15.

// Input
const val = (n % 10) ** 2

// Output (Prettier 1.14)
const val = n % 10 ** 2;

// Output (Prettier 1.15)
const val = (n % 10) ** 2;

Correctly print comments in try..finally (#5252 by @aquibm)

In previous versions, some comments in a try-finally statement were printed in the wrong order. Prettier now prints them correctly.

// Input
// comment 1
try {
    // comment 2
}
// comment 3
finally // comment 4
{
    // comment 5
}

// Output (Prettier 1.14)
// comment 1
try {
  // comment 2
} finally { // comment 4
  // comment 3
  // comment 5
}

// Output (Prettier 1.15)
// comment 1
try {
  // comment 2
} finally {
  // comment 3
  // comment 4
  // comment 5
}

Printing comments in catch clause to the correct place (#5202 by @duailibe)

Comments in catch clauses are now printed on their own line just like other clauses.

// Input
try {} catch (
  // comment
  e
) {}

// Output (Prettier 1.14)
try {
} catch (// comment
e) {}

// Output (Prettier 1.15)
try {
} catch (
  // comment
  e
) {}

Inline the argument if it's an arrow function with conditional expression as body (#5209 by @duailibe)

There's no need to add an extra indentation level for a function call argument that's an arrow function with conditional expression as body. We now inline them in Prettier 1.15.

// Input
x.then(() => a ?
  veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong:
  veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);

// Output (Prettier 1.14)
x.then(
  () =>
    a
      ? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
      : veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);

// Output (Prettier 1.15)
x.then(() =>
  a
    ? veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
    : veryVerVeryveryVerVeryveryVerVeryveryVerVeryLong
);

Fix unexpected indentation in variable declarator caused by comments (#5190 by @duailibe)

In previous versions, comments in variable declarations caused variable declarators to be printed without indentation, but this has been fixed in Prettier 1.15.

// Input
const // Comment
	a = 1;

// Output (Prettier 1.14)
const // Comment
a = 1;

// Output (Prettier 1.15)
const // Comment
  a = 1;

Do not remove parens for ternary in optional member expression (#5179 by @existentialism)

Prettier 1.14 was incorrectly removing parens around ternary operators when they appeared within optional member expressions (?.). Those cases are now printed correctly in Prettier 1.15.

// Input
(a ? b : c)?.d;

// Output (Prettier 1.14)
a ? b : c?.d;

// Output (Prettier 1.15)
(a ? b : c)?.d;

Escape ${ as well as backticks in GraphQL tags (#5137 by @lydell)

Previously, interpolation-like strings were wrongly unescaped in embedded GraphQL, which led to JavaScript treating it as an interpolation. They're correctly escaped in Prettier 1.15.

// Input
const schema = gql`
type Project {
    "Pattern: \`\${project}\`"
    pattern: String
}
`;

// Output (Prettier 1.14)
const schema = gql`
  type Project {
    "Pattern: \`${project}\`"
    pattern: String
  }
`;

// Output (Prettier 1.15)
const schema = gql`
  type Project {
    "Pattern: \`\${project}\`"
    pattern: String
  }
`;

Do not strip quotes in keys if they're not es5 compatible (#5157 by @koba04)

Previously, Prettier stripped quotes in keys if they werent necessary in ES2015, which caused the output to be incompatible with ES5. Prettier 1.15 only strips them if they're not necessary in ES5.

// Input
var obj = {
  "𐊧": 'ok',
  𐊧: 'ok'
};

// Output (Prettier 1.14)
var obj = {
  𐊧: "ok",
  𐊧: "ok"
};

// Output (Prettier 1.15)
var obj = {
 "𐊧": "ok",
  𐊧: "ok"
};

Do not hug arguments if the second argument in function is a ternary (#5151 by @onurtemizkan)

We have some special cases that will hug function call arguments if the first one is a function and the second one is a not a complex expression, but we considered ternaries non-complex expressions. They actually can be complex, so weve changed this in Prettier 1.15.

// Input
func(
  () => { thing(); },
  something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0)
);

// Output (Prettier 1.14)
func(() => {
  thing();
}, something(longArgumentName, anotherLongArgumentName) ? someOtherThing() : somethingElse(true, 0));

// Output (Prettier 1.15)
func(
  () => {
    thing();
  },
  something(longArgumentName, anotherLongArgumentName)
    ? someOtherThing()
    : somethingElse(true, 0)
);

Add support for timeouts passed as numbers to test functions (#5085 by @j-f1)

This preserves Prettiers special formatting for testing functions when a timeout (number) is passed as a third parameter:

// Input
it('Handles at least 10k untracked files without failing', async () => {
  hello()
}, 25000)

// Output (Prettier 1.14)
it(
  "Handles at least 10k untracked files without failing",
  async () => {
    hello();
  },
  25000
);

// Output (Prettier 1.15)
it('Handles at least 10k untracked files without failing', async () => {
  hello()
}, 25000)

Format beforeEach-like calls like regular function calls (#5011 by @ericsakmar)

Previously, arguments in beforeEach were wrongly hugged. We've fixed this issue in Prettier 1.15.

// Input
beforeEach(done =>
  startService()
    .pipe(tap(service => (instance = service)))
    .subscribe(() => done()),
);

// Output (Prettier 1.14)
beforeEach(done =>
  startService()
    .pipe(tap(service => (instance = service)))
    .subscribe(() => done()));

// Output (Prettier 1.15)
beforeEach(done =>
  startService()
    .pipe(tap(service => (instance = service)))
    .subscribe(() => done())
);

Print pipeline operator's leading comment on its own line (#5015 by @flxwu)

In Prettier 1.14, a comment in front of a pipeline operator causes the right argument to be not indented. This issue has been fixed in Prettier 1.15.

// Input
function pipeline() {
	0
	// Comment
	|> x
}

// Output (Prettier 1.14)
function pipeline() {
  0
    |> // Comment
    x;
}

// Output (Prettier 1.15)
function pipeline() {
  0 |>
    // Comment
    x;
}

Preserve dangling comments in new expressions (#5017 by @flxwu)

Passing a comment instead of an expression to a new call is now preserved instead of being pulled out of the parens.

// Input
new Thing(/* comment */)

// Output (Prettier 1.14)
new Thing /* comment */();

// Output (Prettier 1.15)
new Thing(/* comment */);

Remove redundant ASI protection for bind expression (#4970 by @TitanSnow)

Unnecessary semicolons for bind expressions are removed with --no-semi in Prettier 1.15.

// Input
a::b.c

// Output (Prettier 1.14)
;a::b.c

// Output (Prettier 1.15)
a::b.c

Do not remove necessary parens in bind expression (#4964 by @TitanSnow)

Necessary parens in bind expressions are preserved in Prettier 1.15.

// Input
a::(b.c());

// Output (Prettier 1.14)
a::b.c();

// Output (Prettier 1.15)
a::(b.c());

Fix indentation for ternary in function call (#4368 by @malcolmsgroves)

Logical expressions in a ternary in a function call are now indented correctly.

// Input
fn(
  bifornCringerMoshedPerplexSawder,
  askTrovenaBeenaDependsRowans,
  glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
    anodyneCondosMalateOverateRetinol // <--
    ? annularCooeedSplicesWalksWayWay
    : kochabCooieGameOnOboleUnweave
);

// Output (Prettier 1.14)
fn(
  bifornCringerMoshedPerplexSawder,
  askTrovenaBeenaDependsRowans,
  glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
  anodyneCondosMalateOverateRetinol // <--
    ? annularCooeedSplicesWalksWayWay
    : kochabCooieGameOnOboleUnweave
);

// Output (Prettier 1.15)
fn(
  bifornCringerMoshedPerplexSawder,
  askTrovenaBeenaDependsRowans,
  glimseGlyphsHazardNoopsTieTie === averredBathersBoxroomBuggyNurl &&
    anodyneCondosMalateOverateRetinol // <--
    ? annularCooeedSplicesWalksWayWay
    : kochabCooieGameOnOboleUnweave
);

Do not move comments in imports (#5016 by @ericsakmar)

Comments in imports won't be moved output of the import.

// Input
import x, {
  // comment
  y
} from 'z';


// Output (Prettier 1.14)
import x, { y } from "z";
// comment

// Output (Prettier 1.15)
import x, {
  // comment
  y
} from "z";

Fix unstable while comment (#5251 by @jaideng123)

Comments in while are now correctly formatted so that it does not need to be formatted twice to get to a stable output.

// Input
while(
    true
    // Comment
) {}

// First Output (Prettier 1.14)
while (true) // Comment
{}

// Second Output (Prettier 1.14)
while (
  true // Comment
) {}

// First & Second Output (Prettier 1.15)
while (
  true
  // Comment
) {}

Stably print comments between function declaration and its body (#5250 by @jaideng123)

Comments between a function declaration and its body do not need to be formatted twice to get the final result now.

// Input
function foo() // this is a function
{
  return 42
}

// First Output (Prettier 1.14)
function foo() { // this is a function
  return 42;
}

// Second Output (Prettier 1.14)
function foo() {
  // this is a function
  return 42;
}

// First & Second Output (Prettier 1.15)
function foo() {
  // this is a function
  return 42;
}

JSX

Do not break logical expression chain in JSX (#5092 by @duailibe)

Unnecessary indentations for logical expression chains in JSX are now prevented.

// Input
const TestComponent = () => {
  return (
    <>
      {cats && memes && (
        <Foo bar><Trololol /></Foo>
      )}
    </>
  );
}

// Output (Prettier 1.14)
const TestComponent = () => {
  return (
    <>
      {cats &&
        memes && (
          <Foo bar>
            <Trololol />
          </Foo>
        )}
    </>
  );
};

// Output (Prettier 1.15)
const TestComponent = () => {
  return (
    <>
      {cats && memes && (
        <Foo bar>
          <Trololol />
        </Foo>
      )}
    </>
  );
};

Do not change non-breaking whitespace into the regular one (#5165 by @vjeux, #5334 by @ikatyang)

Previously, non-breaking whitespaces were treated as regular whitespaces, which caused them to be replaced with regular whitespaces. This issue has been fixed in Prettier 1.15.

(· represents a non-breaking whitespace)

// Input
function OhMyWhitespace() {
  return (
    <Dialog>
      <p>
        Supprimer lobjectif «·{goal.name}·»·?
      </p>
    </Dialog>
  )
}

// Output (Prettier 1.14)
function OhMyWhitespace() {
  return (
    <Dialog>
      <p>
        Supprimer lobjectif «
        {goal.name}
        ·»·?
      </p>
    </Dialog>
  );
}

// Output (Prettier 1.15)
function OhMyWhitespace() {
  return (
    <Dialog>
      <p>Supprimer lobjectif «·{goal.name}·»·?</p>
    </Dialog>
  );
}

Do not break simple jsx opening tag (#5078 by @duailibe)

Simple jsx opening tags are no longer broken onto multiple lines.

// Input
function HelloWorld() {
  const listItemText = (
    <ListItemText
      primary={
        <PrimaryText>{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
      }
    />
  );
}

// Output (Prettier 1.14)
function HelloWorld() {
  const listItemText = (
    <ListItemText
      primary={
        <PrimaryText
        >{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
      }
    />
  );
}

// Output (Prettier 1.15)
function HelloWorld() {
  const listItemText = (
    <ListItemText
      primary={
        <PrimaryText>{`Two Factor Authentication is ${enabledText}`}</PrimaryText>
      }
    />
  );
}

Fix a regression for arrow function in jsx expression (#5063 by @ikatyang)

// Input
<div className="search-filter-chips">
    {scopes.filter(scope => scope.value !== "").map((scope, i) => (
        <FilterChip
            query={this.props.query}
            onFilterChosen={this.onSearchScopeClicked}
        />
    ))}
</div>;

// Output (Prettier 1.14)
<div className="search-filter-chips">
  {scopes.filter(scope => scope.value !== "").map((scope, i) => (
    <FilterChip
      query={this.props.query}
      onFilterChosen={this.onSearchScopeClicked}
    />
  ))}
</div>;

// Output (Prettier 1.15)
<div className="search-filter-chips">
  {scopes
    .filter(scope => scope.value !== "")
    .map((scope, i) => (
      <FilterChip
        query={this.props.query}
        onFilterChosen={this.onSearchScopeClicked}
      />
    ))}
</div>;

Flow

Inline generics with a single identifier (#5066 by @duailibe)

Generics with a single identifier are now always inlined.

// Input
const longVariableName: Array<number> = this.foo.bar.baz.collider.body.vertices.reduce();

// Output (Prettier 1.14)
const longVariableName: Array<
  number
> = this.foo.bar.baz.collider.body.vertices.reduce();

// Output (Prettier 1.15)
const longVariableName: Array<number> = this.foo.bar.baz.collider.body.vertices.reduce();

Do not always inline classes in extends (#5244 by @aquibm)

Classes in extends are now correctly broken into multiple lines.

// Input
declare interface ExtendsMany extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
  x: string;
}

// Output (Prettier 1.14)
declare interface ExtendsMany
  extends Interface1, Interface2, Interface3, Interface4, Interface5, Interface6, Interface7 {
  x: string;
}

// Output (Prettier 1.15)
declare interface ExtendsMany
  extends Interface1,
    Interface2,
    Interface3,
    Interface4,
    Interface5,
    Interface6,
    Interface7 {
  x: string;
}

Do not add unnecessary parens for async function in export default (#5303 by @jbrown215)

Unnecessary parens around export default async function are now removed. This error occurred only when using the flow parser.

// Input
export default async function foo() {};

// Output (Prettier 1.14)
export default (async function foo() {});

// Output (Prettier 1.15)
export default async function foo() {}

TypeScript

Add ASI protection for non-null assertion (#5262 by @duailibe)

Necessary semicolons for non-null assertions won't be removed in --no-semi mode.

// Input
const el = ReactDOM.findDOMNode(ref)
;(el as HTMLElement)!.style.cursor = 'pointer'

// Output (Prettier 1.14)
const el = ReactDOM.findDOMNode(ref)
(el as HTMLElement)!.style.cursor = "pointer"

// Output (Prettier 1.15)
const el = ReactDOM.findDOMNode(ref)
;(el as HTMLElement)!.style.cursor = "pointer"

Do not add extra semicolon for method signature when prettier-ignore is used (#5160 by @onurtemizkan)

Extra semicolon for method signature is removed in Prettier 1.15.

// Input
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
    // prettier-ignore
    addEventListener(): void;
    addEventListener(type: string): void;
}

// Output (Prettier 1.14)
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
  // prettier-ignore
  addEventListener(): void;;
  addEventListener(type: string): void;
}

// Output (Prettier 1.15)
interface SharedWorkerGlobalScope extends WorkerGlobalScope {
  // prettier-ignore
  addEventListener(): void;
  addEventListener(type: string): void;
}

Do not print invalid parens for destructuring with default value (#5096 by @ikatyang)

Previously, Prettier printed invalid parens for destructuring with default value, we fixed this issue in Prettier 1.15.

// Input
({ prop: toAssign = "default" } = { prop: "propval" });

// Output (Prettier 1.14)
({ prop: (toAssign = "default") } = { prop: "propval" });

// Output (Prettier 1.15)
({ prop: toAssign = "default" } = { prop: "propval" });

Do not print semicolon for class properties with modifiers in --no-semi mode (#5083 by @ikatyang)

In Prettier 1.14, semicolons are added to the end of a class property when there are modifiers in its next property, however these semicolons are not needed. Unnecessary semicolons are removed in Prettier 1.15.

// Input
class Reader {
  private [kBuffer]: Buffer
  private [kOffset]: number
}

// Output (1.14)
class Reader {
  private [kBuffer]: Buffer;
  private [kOffset]: number
}

// Output (1.15)
class Reader {
  private [kBuffer]: Buffer
  private [kOffset]: number
}

Do not remove parens for complex nodes in ClassExpression's extends (#5074 by @ikatyang)

Previously, parens for complex nodes in class expression's extends were wrongly removed, producing invalid code. This issue has been fixed in Prettier 1.15.

// Input
let Subclass2 = class extends (Superclass as AssertedSuperclass) {};

// Output (Prettier 1.14)
let Subclass2 = class extends Superclass as AssertedSuperclass {};

// Output (Prettier 1.15)
let Subclass2 = class extends (Superclass as AssertedSuperclass) {};

Do not remove necessary parens for TSOptionalType (#5056 by @ikatyang)

Previously, necessary parens for optional types in tuple were wrongly removed, producing invalid code. This issue has been fixed in Prettier 1.15.

// Input
type T = [("a" | "b")?];

// Output (Prettier 1.14)
type T = ["a" | "b"?];

// Output (Prettier 1.15)
type T = [("a" | "b")?];

CSS

Do not print wrong output if both front matter and /* prettier-ignore */ exist (#5103 by @ikatyang)

In Prettier 1.14, location information in the AST were wrongly shifted due to how we extract front matters from the source, which led to /* prettier-ignore */ producing invalid output. We've fixed this issue in Prettier 1.15.

/* Input */
---
hello: world
---

/* prettier-ignore */
.foo {}

/* Output (Prettier 1.14) */
---
hello: world
---

/* prettier-ignore */
 pretti

/* Output (Prettier 1.15) */
---
hello: world
---

/* prettier-ignore */
.foo {}

Keep newlines in CSS-in-JS Templates (#5240 by @onurtemizkan)

Interpolations in CSS-in-JS templates could be anything, so we keep newlines for them in Prettier 1.15.

// Input
const foo = styled.div`
  ${secondary}
  flex: 0 0 auto;
`;

// Output (Prettier 1.14)
const foo = styled.div`
  ${secondary} flex: 0 0 auto;
`;

// Output (Prettier 1.15)
const foo = styled.div`
  ${secondary}
  flex: 0 0 auto;
`;

Markdown

Trailing spaces for front matters' delimiters are allowed (#5107 by @ikatyang)

Previously, we only detected front matters which did not use trailing spaces for their delimiters, which led to an issue where thematic breaks (i.e., ---) were wrongly recognized as the end of the front matter. We've fixed this issue by allowing trailing spaces for front matters' delimiters in Prettier 1.15, which is also the way how GitHub processes front matters.

(· represents a whitespace)

<!-- Input -->
---
Title: Title
---···

__strong__ **strong**

---

<!-- Output (Prettier 1.14) -->
---
Title: Title
---···
__strong__ **strong**
---

<!-- Output (Prettier 1.15) -->
---
Title: Title
---···

**strong** **strong**

---

Do not add whitespaces between Latin and Hangul (#5040 by @ikatyang)

Previously, we always inserted whitespace between Latin and CJK characters to improve readability, but according to feedback we received, Korean uses conventional spaces, and inserting whitespaces would cause issues for them, so we disabled this behavior for Hangul in Prettier 1.15. Behavior is not changing for Chinese or Japanese.

<!-- Input -->
예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문

<!-- Output (Prettier 1.14) -->
예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문 Latin 예문

<!-- Output (Prettier 1.15) -->
예문Latin예문Latin 예문Latin예문 Latin예문Latin 예문 Latin 예문

Preserve leading and trailing newlines in fenced code block (#5038 by @ikatyang)

In Prettier 1.14, leading and trailing newlines are removed in fenced code block, which causes other plugins (e.g., php) to fail to format these code blocks. Leading and trailing newlines are preserved in Prettier 1.15.

<!-- Input -->
```

hello

```

<!-- Output (Prettier 1.14) -->
```
hello
```

<!-- Output (Prettier 1.15) -->
```

hello

```

Inline footnote definition if there's only a single line paragraph (#5025 by @ikatyang)

Previously, anything that did not fit within the print width in a footnote definition was broken into multiple lines, but breaking a single line paragraph out onto its own was not much of a readability improvement, so we always inline them in Prettier 1.15.

<!-- Input -->
[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.

<!-- Output (Prettier 1.14) -->
[^1]:

  In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.

<!-- Output (Prettier 1.15) -->
[^1]: In eos repellat fugit dolor veritatis doloremque nobis. Provident ut est illo.

Correctly print lists in front of whitespace-only trailing newlines (#5024 by @ikatyang)

In Prettier 1.14, lists in front of whitespace-only trailing newlines are wrongly recognized as loose lists. This caused an issue where the user would need to format their code twice to get it stable, but when the code stabilized, it would produce the wrong output. This issue has been fixed in Prettier 1.15.

// Input
if (condition) {
  md`
- 123
  - 456
`;
}

// First Output (Prettier 1.14)
if (condition) {
  md`
- 123
  - 456
  `;
}

// Second Output (Prettier 1.14)
if (condition) {
  md`
- 123

  - 456
  `;
}

// First & Second Output (Prettier 1.15)
if (true) {
  md`
- 123
  - 456
  `;
}

YAML

Escape quotes correctly (#5236 by @ikatyang)

Previously, string with escaped quotes in doubleQuote would cause invalid output. They're now correctly escaped in Prettier 1.15.

# Input
"'a\"b"

# Output (Prettier 1.14)
''a"b'

# Output (Prettier 1.15)
'''a"b'

Preserve trailing comments for document and document head (#5027 by @ikatyang)

In Prettier 1.14, there were some situations where trailing comments for document and document head may be moved. In Prettier 1.15, they're now always preserved.

# Input
--- # hello
... # world

# Output (Prettier 1.14)
# hello
# world

# Output (Prettier 1.15)
--- # hello
... # world

Do not throw error for flow mapping item with long value (#5027 by @ikatyang)

Previously, long flow mapping values were wrongly recognized as keys, which produced syntax errors since implicit keys with more than 1024 characters are not allowed. This issue has been fixed in Prettier 1.15.

(long represents a long text that is more than 1024 characters)

# Input
{x: long}

# Output (Prettier 1.14)
SyntaxError: The "undefine...ndefined" key is too long

# Output (Prettier 1.15)
{
  x: long
}

Prefer implicit key for empty mapping value (#4972 by @ikatyang)

Previously, a mapping item with an empty value was always printed with an explicit key, which is not that common and this confused people. In Prettier 1.15, we always print it with an implicit key in that situations.

# Input
a:
  b:

# Output (Prettier 1.14)
a:
  ? b

# Output (Prettier 1.15)
a:
  b:

Thanks! ❤️

Thanks to everyone who contributed to this release, as well as those who raised issues and gave us feedback. Prettier is a community-driven project and is only able to continue to exist thanks to people like you. Thank you!

Special thanks to @j-f1, @suchipi and @existentialism for reviewing this blog post!