diff --git a/scripts/draft-blog-post.js b/scripts/draft-blog-post.js new file mode 100644 index 000000000000..14d93cfc2c68 --- /dev/null +++ b/scripts/draft-blog-post.js @@ -0,0 +1,87 @@ +"use strict"; + +const fs = require("fs"); +const path = require("path"); + +const changelogUnreleasedDir = path.join(__dirname, "../changelog_unreleased"); +const blogDir = path.join(__dirname, "../website/blog"); + +const version = require("../package.json").version.replace(/-.+/, ""); +const versionShort = version.replace(/\.0$/, ""); + +const categories = [ + { dir: "javascript", title: "JavaScript" }, + { dir: "typescript", title: "TypeScript" }, + { dir: "flow", title: "Flow" }, + { dir: "json", title: "JSON" }, + { dir: "css", title: "CSS" }, + { dir: "scss", title: "SCSS" }, + { dir: "less", title: "Less" }, + { dir: "html", title: "HTML" }, + { dir: "vue", title: "Vue" }, + { dir: "angular", title: "Angular" }, + { dir: "lwc", title: "LWC" }, + { dir: "handlebars", title: "Handlebars" }, + { dir: "graphql", title: "GraphQL" }, + { dir: "markdown", title: "Markdown" }, + { dir: "mdx", title: "MDX" }, + { dir: "yaml", title: "YAML" }, + { dir: "api", title: "API" }, + { dir: "cli", title: "CLI" } +]; + +const categoriesByDir = categories.reduce((result, category) => { + result[category.dir] = category; + return result; +}, {}); + +const dirs = fs + .readdirSync(changelogUnreleasedDir, { withFileTypes: true }) + .filter(entry => entry.isDirectory()); + +for (const dir of dirs) { + const dirPath = path.join(changelogUnreleasedDir, dir.name); + const category = categoriesByDir[dir.name]; + + if (!category) { + throw new Error("Unknown category: " + dir.name); + } + + category.entries = fs + .readdirSync(path.join(changelogUnreleasedDir, dir.name)) + .filter(fileName => /^pr-\d+\.md$/.test(fileName)) + .map(fileName => + fs + .readFileSync(path.join(dirPath, fileName), "utf8") + .trim() + .replace(/^#### [a-z]/, s => s.toUpperCase()) + ); +} + +const result = [ + `--- +author: "🚧" +authorURL: "https://github.com/🚧" +title: "Prettier ${versionShort}: 🚧" +---`, + "🚧 Write an introduction here.", + "", + "## Highlights", + "🚧 Move the most interesting changes here.", + "## Other changes" +]; + +for (const category of categories) { + if (!category.entries || category.entries.length === 0) { + continue; + } + + result.push("### " + category.title); + + result.push(...category.entries); +} + +fs.writeFileSync( + path.join(blogDir, `${new Date().getFullYear()}-xx-xx-${version}.md`), + result.join("\n\n") + "\n" +); diff --git a/website/blog/2020-xx-xx-2.0.0.md b/website/blog/2020-xx-xx-2.0.0.md new file mode 100644 index 000000000000..1042c0b5ffc4 --- /dev/null +++ b/website/blog/2020-xx-xx-2.0.0.md @@ -0,0 +1,1318 @@ +--- +author: "🚧" +authorURL: "https://github.com/🚧" +title: "Prettier 2.0: 🚧" +--- + +🚧 Write an introduction here. + + + +## Highlights + +🚧 Move the most interesting changes here. + +## Other changes + +### JavaScript + +#### Always add a space after the `function` keyword ([#3903](https://github.com/prettier/prettier/pull/3903) by [@j-f1](https://github.com/j-f1), [@josephfrazier](https://github.com/josephfrazier), [@sosukesuzuki](https://github.com/sosukesuzuki), [@thorn0](https://github.com/thorn0)) + +Previously, a space would be added after the `function` keyword in function declarations, but not in function expressions. Now, for consistency, a space is always added after the `function` keyword, including in generators. Also, a space is now added between `yield` and `*`, which can help with [catching bugs](https://github.com/prettier/prettier/issues/7028#user-content-bugs). + + +```js +// Input +const identity = function (value) { + return value; +}; +function identity (value) { + return value; +} +function * getRawText() { + for (const token of tokens) { + yield* token.getRawText(); + } +} +const f = function(value: T) {} + +// Prettier stable +const identity = function(value) { + return value; +}; +function identity(value) { + return value; +} +function* getRawText() { + for (const token of tokens) { + yield* token.getRawText(); + } +} +const f = function(value: T) {}; + +// Prettier master +const identity = function (value) { + return value; +}; +function identity(value) { + return value; +} +function *getRawText() { + for (const token of tokens) { + yield *token.getRawText(); + } +} +const f = function (value: T) {}; +``` + +#### Method chain breaking ([#6685](https://github.com/prettier/prettier/pull/6685) by [@mmkal](https://github.com/mmkal)) + +Previously, any chained method calls of length three or longer would be automatically broken. This uses a heuristic for the complexity of the arguments in the chain, rather than just the chain length. Now, if chained method calls have arguments which aren't easy to understand at a glance (e.g. functions or deeply-nested objects), the chain is broken. Otherwise, they're allowed to remain on one line. See prior issues [#3197](https://github.com/prettier/prettier/issues/3107), [#4765](https://github.com/prettier/prettier/pull/4765), [#1565](https://github.com/prettier/prettier/issues/1565) and [#4125](https://github.com/prettier/prettier/pull/4125) for context and examples. + + +```javascript +// Input +foo.one().two().three() === bar.four().five().six(); + +// Output (Prettier stable) +foo + .one() + .two() + .three() === + bar + .four() + .five() + .six(); + +// Output (Prettier master) +foo.one().two().three() === bar.four().five().six(); +``` + +#### Fix formatting of labeled statements with comments ([#6984](https://github.com/prettier/prettier/pull/6984) by [@clement26695](https://github.com/clement26695)) + +Formatting of comments in labeled statements was not stable + + +```jsx +// Input +loop1: +//test +const i = 3; + +// Prettier stable (first output) +loop1: //test +const i = 3; + +// Prettier stable (second output) +//test +loop1: const i = 3; + +// Prettier master (first output) +//test +loop1: const i = 3; +``` + +#### Fix formatting of logical, binary and sequence expressions in template literals ([#7010](https://github.com/prettier/prettier/pull/7010) by [@evilebottnawi](https://github.com/evilebottnawi)) + + +```js +// Input +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${foo || bar}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${foo | bar}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(foo, bar)}`; + +// Prettier stable +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${foo || + bar}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${foo | + bar}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${(foo, +bar)}`; + +// Prettier master +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${ + foo || bar +}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${ + foo | bar +}`; +`111111111 222222222 333333333 444444444 555555555 666666666 777777777 ${ + (foo, bar) +}`; +``` + +#### Preserve parentheses for JSDoc type casting with extra spaces and asterisk at end ([#7011](https://github.com/prettier/prettier/pull/7011) by [@evilebottnawi](https://github.com/evilebottnawi)) + +Formatting of comments in labeled statements was not stable + + +```javascript +// Input +const foo = /** @type {!Foo} **/ (baz); +const bar = /** @type {!Foo} * * */(baz); + +// Prettier stable +const foo = /** @type {!Foo} **/ baz; +const bar = /** @type {!Foo} * * */ baz; + +// Prettier master +const foo = /** @type {!Foo} **/ (baz); +const bar = /** @type {!Foo} * * */ (baz); +``` + +#### Fix unstable formatting of logical expressions ([#7026](https://github.com/prettier/prettier/pull/7026) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +const averredBathersBoxroomBuggyNurl = + bifornCringerMoshedPerplexSawder === 1 || + (askTrovenaBeenaDependsRowans === 2 || glimseGlyphsHazardNoopsTieTie === 3); + +// Prettier stable (first output) +const averredBathersBoxroomBuggyNurl = + bifornCringerMoshedPerplexSawder === 1 || + askTrovenaBeenaDependsRowans === 2 || glimseGlyphsHazardNoopsTieTie === 3; + +// Prettier stable (second output) +const averredBathersBoxroomBuggyNurl = + bifornCringerMoshedPerplexSawder === 1 || + askTrovenaBeenaDependsRowans === 2 || + glimseGlyphsHazardNoopsTieTie === 3; + +// Prettier master (first output) +const averredBathersBoxroomBuggyNurl = + bifornCringerMoshedPerplexSawder === 1 || + askTrovenaBeenaDependsRowans === 2 || + glimseGlyphsHazardNoopsTieTie === 3; +``` + +#### Format `throw` like `return` ([#7070](https://github.com/prettier/prettier/pull/7070) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```js +// Input +function foo() { + throw this.hasPlugin("dynamicImports") && this.lookahead().type === tt.parenLeft.right; +} + +// Prettier stable +function foo() { + throw this.hasPlugin("dynamicImports") && + this.lookahead().type === tt.parenLeft.right; +} + + +// Prettier master +function foo() { + throw ( + this.hasPlugin("dynamicImports") && + this.lookahead().type === tt.parenLeft.right + ); +} +``` + +#### Fix indentation in ternaries nested in conditions of other ternaries ([#7087](https://github.com/prettier/prettier/pull/7087) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +const foo = (number % 10 >= 2 && (number % 100 < 10 || number % 100 >= 20) ? +kochabCooieGameOnOboleUnweave : annularCooeedSplicesWalksWayWay) +? anodyneCondosMalateOverateRetinol : averredBathersBoxroomBuggyNurl; + +// Prettier stable +const foo = (number % 10 >= 2 && (number % 100 < 10 || number % 100 >= 20) +? kochabCooieGameOnOboleUnweave +: annularCooeedSplicesWalksWayWay) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; + +// Prettier master +const foo = ( + number % 10 >= 2 && (number % 100 < 10 || number % 100 >= 20) + ? kochabCooieGameOnOboleUnweave + : annularCooeedSplicesWalksWayWay +) + ? anodyneCondosMalateOverateRetinol + : averredBathersBoxroomBuggyNurl; +``` + +#### Tweak function composition logic for decorators ([#7138](https://github.com/prettier/prettier/pull/7138) by [@brainkim](https://github.com/brainkim)) + +Because decorators modify the line following, splitting a decorator call’s +arguments onto multiple lines can obscure the relationship between the +decorator and its intended target, producing less-readable code. Therefore, the +function composition logic introduced in #6033 has been changed to exclude +decorator calls. + + +```jsx +// Input +export class Item { + @OneToOne(() => Thing, x => x.item) + thing!: Thing; +} + +// Output (Prettier stable) +export class Item { + @OneToOne( + () => Thing, + x => x.item, + ) + thing!: Thing; +} + +// Output (Prettier master) +export class Item { + @OneToOne(() => Thing, x => x.item) + thing!: Thing; +} +``` + +#### Fix moving semicolon to trailing comment in `return` ([#7140](https://github.com/prettier/prettier/pull/7140) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```js +// Input +return // comment +; + +// Prettier stable +return // comment; + +// Prettier master +return; // comment +``` + +#### Fix: remove unnecessary parens when yielding jsx ([#7367](https://github.com/prettier/prettier/pull/7367) by [@cola119](https://github.com/cola119)) + + +```jsx +// Input +function* f() { + yield
generator
+} + +// Prettier stable +function* f() { + yield (
generator
); +} + +// Prettier master +function* f() { + yield
generator
+} +``` + +### TypeScript + +#### Fix formatting of type operator as arrow function return type ([#6901](https://github.com/prettier/prettier/pull/6901) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```ts +// Input +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly["attributes"] & undefined +> => {}; + +// Prettier stable +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise => {}; + +// Prettier master +export const getVehicleDescriptor = async ( + vehicleId: string +): Promise< + Collections.Parts.PrintedCircuitBoardAssembly["attributes"] & undefined +> => {}; +``` + +#### Print JSDoc-only types as is instead of throwing strange errors ([#7020](https://github.com/prettier/prettier/pull/7020) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +function fromFlow(arg: ?Maybe) {} + +// Prettier stable +Error: unknown type: "TSJSDocNullableType" + at printPathNoParens (https://prettier.io/lib/standalone.js:26012:13) + at Object.genericPrint$3 [as print] (https://prettier.io/lib/standalone.js:23541:28) + +// Prettier master +function fromFlow(arg: ?Maybe) {} +``` + +#### Don't print trailing commas after rest elements in tuples ([#7075](https://github.com/prettier/prettier/pull/7075) by [@thorn0](https://github.com/thorn0)) + +- A rest element is always the last element of a tuple type. Nothing can be added after it. +- While TS is okay with this comma, [Babel doesn't parse it](https://github.com/babel/babel/issues/10769) +- In function parameters and array destructuring, such a comma is a syntax error. Keeping it in tuples is inconsistent. + + +```jsx +// Input +type ValidateArgs = [ + { + [key: string]: any; + }, + string, + ...string[], +]; + +// Prettier stable +type ValidateArgs = [ + { + [key: string]: any; + }, + string, + ...string[], +]; + +// Prettier master +type ValidateArgs = [ + { + [key: string]: any; + }, + string, + ...string[] +]; +``` + +#### Remove extra indentation for arrow function on variable declaration with comment ([#7094](https://github.com/prettier/prettier/pull/7094) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```ts +// Input +const foo = () => { + return; +} + +// foo +; + +// Prettier stable +const foo = () => { + return; + }; + + // foo + +// Prettier master +const foo = () => { + return; +}; + +// foo +``` + +#### Fix printing of comments in function types ([#7104](https://github.com/prettier/prettier/pull/7104) by [@thorn0](https://github.com/thorn0)) + + +```ts +// Input +type f1 = ( + currentRequest: {a: number}, + // TODO this is a very very very very long comment that makes it go > 80 columns +) => number; + +// Prettier stable +type f1 = (currentRequest: { + a: number; +}) => // TODO this is a very very very very long comment that makes it go > 80 columns +number; + +// Prettier master +type f1 = ( + currentRequest: { a: number } + // TODO this is a very very very very long comment that makes it go > 80 columns +) => number; +``` + +#### Fix formatting comments for function-like nodes ([#7144](https://github.com/prettier/prettier/pull/7144) by [@armano2](https://github.com/armano2)) + + +```ts +// Input +interface foo1 { + bar1/* foo */ (/* baz */) // bat + bar2/* foo */ ? /* bar */ (/* baz */) /* bat */; + bar3/* foo */ (/* baz */) /* bat */ + bar4/* foo */ ? /* bar */ (bar: /* baz */ string): /* bat */ string; + /* foo */ (/* bar */): /* baz */ string; + /* foo */ (bar: /* bar */ string): /* baz */ string; + /* foo */ new /* bar */ (a: /* baz */ string): /* bat */ string + /* foo */ new /* bar */ (/* baz */): /* bat */ string +} + +type foo7 = /* foo */ (/* bar */) /* baz */ => void +type foo8 = /* foo */ (a: /* bar */ string) /* baz */ => void +let foo9: new /* foo */ (/* bar */) /* baz */ => string; +let foo10: new /* foo */ (a: /* bar */ string) /* baz */ => string; + +// Prettier stable +interface foo1 { + bar1 /* foo */ /* baz */(); // bat + bar2 /* foo */ /* bar */ /* baz */ /* bat */?(); + bar3 /* foo */ /* baz */() /* bat */; + bar4 /* foo */?(/* bar */ bar: /* baz */ string): /* bat */ string; + /* foo */ (): /* bar */ /* baz */ string; + /* foo */ (bar: /* bar */ string): /* baz */ string; + /* foo */ new (/* bar */ a: /* baz */ string): /* bat */ string; + /* foo */ new (): /* bar */ /* baz */ /* bat */ string; +} + +type foo7 = /* foo */ () => /* bar */ /* baz */ void; +type foo8 = /* foo */ (a: /* bar */ string) => /* baz */ void; +let foo9: new () => /* foo */ /* bar */ /* baz */ string; +let foo10: new (/* foo */ a: /* bar */ string) => /* baz */ string; + +// Prettier master +interface foo1 { + bar1 /* foo */(/* baz */); // bat + bar2 /* foo */ /* bar */?(/* baz */) /* bat */; + bar3 /* foo */(/* baz */) /* bat */; + bar4 /* foo */?(/* bar */ bar: /* baz */ string): /* bat */ string; + /* foo */ (/* bar */): /* baz */ string; + /* foo */ (bar: /* bar */ string): /* baz */ string; + /* foo */ new (/* bar */ a: /* baz */ string): /* bat */ string; + /* foo */ new (/* baz */): /* bar */ /* bat */ string; +} + +type foo7 = /* foo */ (/* bar */) => /* baz */ void; +type foo8 = /* foo */ (a: /* bar */ string) => /* baz */ void; +let foo9: new (/* bar */) => /* foo */ /* baz */ string; +let foo10: new (/* foo */ a: /* bar */ string) => /* baz */ string; +``` + +```ts +// Input +abstract class Test { + abstract foo12 /* foo */ (a: /* bar */ string): /* baz */ void + abstract foo13 /* foo */ (/* bar */) /* baz */ +} + +// Prettier stable +Error: Comment "foo" was not printed. Please report this error! + at https://prettier.io/lib/standalone.js:15543:15 + at Array.forEach () + at ensureAllCommentsPrinted (https://prettier.io/lib/standalone.js:15541:17) + at coreFormat (https://prettier.io/lib/standalone.js:15592:5) + at format (https://prettier.io/lib/standalone.js:15832:75) + at formatWithCursor (https://prettier.io/lib/standalone.js:15848:14) + at https://prettier.io/lib/standalone.js:31794:17 + at Object.format (https://prettier.io/lib/standalone.js:31802:14) + at formatCode (https://prettier.io/worker.js:234:21) + at handleMessage (https://prettier.io/worker.js:185:18) + +// Prettier master +abstract class Test { + abstract foo12 /* foo */(a: /* bar */ string): /* baz */ void; + abstract foo13 /* foo */(/* bar */); /* baz */ +} +``` + +#### Fix printing of mapped types with the template type omitted ([#7221](https://github.com/prettier/prettier/pull/7221) by [@cola119](https://github.com/cola119)) + + +```ts +// Input +type A = { [key in B] }; + +// Prettier stable +type A = { [key in B]: }; + +// Prettier master +type A = { [key in B] }; +``` + +#### Fix edge cases of printing index signatures ([#7228](https://github.com/prettier/prettier/pull/7228) by [@cola119](https://github.com/cola119)) + +Even though index signatures without type annotations or with multiple parameters aren't valid TypeScript, the TypeScript parser supports this syntax. In line with the [previous error recovery efforts](https://prettier.io/blog/2019/11/09/1.19.0.html#enable-formatting-even-if-there-are-parse-errors-in-some-cases-6816-by-thorn0-and-the-babel-team), Prettier now makes sure its output still can be parsed in these cases. Previous versions produced unparseable code. + + +```ts +// Input +type A = { [key: string] }; +type B = { [a: string, b: string]: string; }; + +// Prettier stable +type A = { [key: string]: }; +type B = { [a: stringb: string]: string }; + +// Prettier master +type A = { [key: string] }; +type B = { [a: string, b: string]: string }; +``` + +### CSS + +#### Don't lowercase element names in CSS selectors ([#6947](https://github.com/prettier/prettier/pull/6947) by [@ark120202](https://github.com/ark120202)) + +Previously, Prettier already preserved casing of unknown element names, but it did lowercase names of HTML elements. +This caused issues when CSS was applied to a case-sensitive document and an there was an element with the same name as in HTML, which is the case in NativeScript. +Prettier now always preserves original casing. + + +```css +/* Input */ +Label { +} + +/* Prettier stable */ +label { +} + +/* Prettier master */ +Label { +} +``` + +### SCSS + +#### Don't add extra comma after last comment in map ([#6918](https://github.com/prettier/prettier/pull/6918) by [@fisker](https://github.com/fisker)) + +Previously, when `trailingComma` set to `es5`, extra comma added after last comment in map. + + +```scss +// Input +$my-map: ( + 'foo': 1, // Comment + 'bar': 2, // Comment +); + +// Prettier stable +$my-map: ( + "foo": 1, + // Comment + "bar": 2, + // Comment, +); + +// Prettier master +$my-map: ( + "foo": 1, + // Comment + "bar": 2, + // Comment +); +``` + +#### Fix scss variable string concatenation removing spaces ([#7211](https://github.com/prettier/prettier/pull/7211) by [@sasurau4](https://github.com/sasurau4)) + +Previously, when Prettier format the scss variable string concatenation, it would remove spaces. Now, Prettier insert spaces around plus operator. + + +```scss +// Input +a { + background-image: url($test-path + 'static/test.jpg'); +} + +// Prettier stable +a { + background-image: url($test-path+"static/test.jpg"); +} + +// Prettier master +a { + background-image: url($test-path + "static/test.jpg"); +} +``` + +### HTML + +#### Comments in `pre` tags caused bad formatting of following closing tag ([#5959](https://github.com/prettier/prettier/pull/5959) by [@selvazhagan](https://github.com/selvazhagan)) + + +``` + +
+
+    
+  
+ + +
+
+    
+  
+ + +
+
+    
+  
+
+``` + +#### Don't treat colons as namespace prefix delimiters in tag names ([#7273](https://github.com/prettier/prettier/pull/7273) by [@fisker](https://github.com/fisker)) + +In HTML5, colons don't have any special meaning in tag names. Previously, Prettier treated them the XML way, as namespace prefix delimiters, but no more. In practice, this means that tags whose ancestors have colons in their names are now treated as usual HTML tags: if they're known standard tags, their names can be lowercased and assumptions can be made about their whitespace sensitivity; custom elements whose names are unknown to Prettier retain the casing of their names and are treated as inline with `--html-whitespace-sensitivity css`. + + +```html + + +
looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog block
+
block
block
block
block
block
+
 pre pr
+e
+ + looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog inline + inline inline inline inline +
+ + + +
+ looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog block +
+
block
block
block
block
block
+
 pre pr e
+ + + looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog inline + + inline inline inline inline +
+ + + +
+ looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog block +
+
block
+
block
+
block
+
block
+
block
+
+ pre pr
+e
+ + + looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooog inline + + inline inline inline inline +
+``` + +#### Do not throw on broken html ([#7293](https://github.com/prettier/prettier/pull/7293) by [@fisker](https://github.com/fisker)) + + +```html + +
+< + + +TypeError: Cannot read property 'start' of null + at hasTrailingLineBreak (https://prettier.io/lib/standalone.js:19694:169) + at forceBreakContent (https://prettier.io/lib/standalone.js:19668:154) + at Object.genericPrint$2 [as print] (https://prettier.io/lib/standalone.js:21068:126) + at callPluginPrintFunction (https://prettier.io/lib/standalone.js:15302:20) + at https://prettier.io/lib/standalone.js:15253:18 + at Object.printComments (https://prettier.io/lib/standalone.js:14974:19) + at printGenerically (https://prettier.io/lib/standalone.js:15252:24) + at printChild (https://prettier.io/lib/standalone.js:21227:14) + at https://prettier.io/lib/standalone.js:21211:104 + at FastPath.map (https://prettier.io/lib/standalone.js:15155:23) + + +
<
+``` + +#### Fix srcset parse error ([#7295](https://github.com/prettier/prettier/pull/7295) by [@fisker](https://github.com/fisker)) + + +```html + + + + +Error: Mixed descriptor in srcset is not supported + at printImgSrcset (https://prettier.io/lib/standalone.js:20867:13) + at printEmbeddedAttributeValue (https://prettier.io/lib/standalone.js:21538:26) + at Object.embed$2 [as embed] (https://prettier.io/lib/standalone.js:21009:43) + at Object.printSubtree (https://prettier.io/lib/standalone.js:15170:30) + at callPluginPrintFunction (https://prettier.io/lib/standalone.js:15288:31) + at https://prettier.io/lib/standalone.js:15253:18 + at Object.printComments (https://prettier.io/lib/standalone.js:14974:19) + at printGenerically (https://prettier.io/lib/standalone.js:15252:24) + at https://prettier.io/lib/standalone.js:21285:175 + at FastPath.map (https://prettier.io/lib/standalone.js:15155:23) + + + +``` + +#### Fix error throws on unclosed tag in `pre` tag ([#7392](https://github.com/prettier/prettier/pull/7392) by [@fisker](https://github.com/fisker)) + + +```html + +

+

+ + +TypeError: Cannot read property 'start' of null + at printChild (https://prettier.io/lib/standalone.js:21224:358) + at https://prettier.io/lib/standalone.js:21211:104 + at FastPath.map (https://prettier.io/lib/standalone.js:15155:23) + at printChildren$1 (https://prettier.io/lib/standalone.js:21155:26) + at Object.genericPrint$2 [as print] (https://prettier.io/lib/standalone.js:21039:41) + at callPluginPrintFunction (https://prettier.io/lib/standalone.js:15302:20) + at https://prettier.io/lib/standalone.js:15253:18 + at Object.printComments (https://prettier.io/lib/standalone.js:14974:19) + at printGenerically (https://prettier.io/lib/standalone.js:15252:24) + at printAstToDoc (https://prettier.io/lib/standalone.js:15264:15) + + +

+

+``` + +### Vue + +#### Format vue SFC containing JSX script ([#7180](https://github.com/prettier/prettier/pull/7180) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```html + + + + + + + + +``` + +### Angular + +#### Fix formatting i18n attributes ([#7371](https://github.com/prettier/prettier/pull/7371) by [@thorn0](https://github.com/thorn0)) + +Prettier 1.19 [added](https://prettier.io/blog/2019/11/09/1.19.0.html#add-formatting-for-i18n-attributes-6695-by-voithos) +support for formatting [i18n attributes](https://angular.io/guide/i18n), but putting the closing quote mark on a new line +broke [custom ids](https://angular.io/guide/i18n#set-a-custom-id-for-persistence-and-maintenance). This is fixed now. + + +```html + +
+ + +
+ + +
+``` + +### Handlebars + +#### Fix superfluous line breaks in ConcatStatement ([#7051](https://github.com/prettier/prettier/pull/7051) by [@dcyriller](https://github.com/dcyriller)) + + +```hbs +{{!-- input --}} +Link + +{{!-- Prettier stable --}} + + Link + + +{{!-- Prettier master --}} + + Link + +``` + +and + +```hbs +{{!-- input --}} +
+ Hello +
+ +{{!-- Prettier stable --}} +
+ Hello +
+ +{{!-- Prettier master --}} +
+ Hello +
+``` + +#### Fix a falling mustache issue ([#7052](https://github.com/prettier/prettier/pull/7052) by [@dcyriller](https://github.com/dcyriller)) + + +```hbs +{{!-- input --}} + + +{{!-- stable --}} + + +{{!-- master --}} + +``` + +#### Improve MustacheStatement printing ([#7157](https://github.com/prettier/prettier/pull/7157) by [@dcyriller](https://github.com/dcyriller)) + + +```hbs +{{!-- input --}} +

Hi here is your name, as it will be displayed {{firstName}} {{lastName}} , welcome!

+ +{{!-- stable --}} +

+ Hi here is your name, as it will be displayed {{firstName}} {{lastName + }} , welcome! +

+ +{{!-- master --}} +

+ Hi here is your name, as it will be displayed {{firstName}} {{ + lastName + }} , welcome! +

+``` + +#### Glimmer: Add prettier-ignore ([#7275](https://github.com/prettier/prettier/pull/7275) by [@chadian](https://github.com/chadian)) + + +```hbs +{{! Input}} +{{! prettier-ignore }} +
+ "hello! my parent was ignored" + {{#my-crazy-component "shall" be="preserved"}} + + {{/my-crazy-component}} +
+ +{{#a-normal-component isRestoredTo = "order" }} + +{{/a-normal-component}} + +{{! Prettier stable}} +{{! prettier-ignore }} +
+ "hello! my parent was ignored" + {{#my-crazy-component "shall" be="preserved"}} + + {{/my-crazy-component}} +
+ +{{#a-normal-component isRestoredTo="order"}} + +{{/a-normal-component}} + +{{! Prettier master}} +{{! prettier-ignore }} +
+ "hello! my parent was ignored" + {{#my-crazy-component "shall" be="preserved"}} + + {{/my-crazy-component}} +
+ +{{#a-normal-component isRestoredTo='order'}} + +{{/a-normal-component}} +``` + +#### Support printing inline handlebars in html (through embed function) ([#7306](https://github.com/prettier/prettier/pull/7306) by [@dcyriller](https://github.com/dcyriller)) + + +``` + + + + + + + + +``` + +### GraphQL + +#### Improve detection of separator between interfaces ([#7305](https://github.com/prettier/prettier/pull/7305) by [@fisker](https://github.com/fisker)) + +Even though using a comma to separate multiple implemented interfaces is deprecated syntax, in order to support legacy use cases, Prettier keeps the original separator and doesn't wilfully replace commas with ampersands. Previously, however, this logic contained a bug, so the wrong separator could end up in the output. This is fixed now. + + +```graphql +# Input +type Type1 implements A, B +# { & <-- Removing this comment changes the separator in stable +{a: a} + +type Type2 implements A, B & C{a: a} + +# Prettier stable +type Type1 implements A & B { + # { & <-- Removing this comment changes the separator in stable + a: a +} + +type Type2 implements A & B & C { + a: a +} + +# Prettier master +type Type1 implements A, B { + # { & <-- Removing this comment changes the separator in stable + a: a +} + +type Type2 implements A, B & C { + a: a +} +``` + +### Markdown + +#### Handle zero-based lists correctly ([#6852](https://github.com/prettier/prettier/pull/6852) by [@evilebottnawi](https://github.com/evilebottnawi)) + + +```md + +0. List +1. List +2. List + + +0. List +1. List +1. List + + +0. List +1. List +2. List +``` + +#### Fix redundant leading spaces in lists ([#7178](https://github.com/prettier/prettier/pull/7178) by [@sasurau4](https://github.com/sasurau4)) + + +```md + +- a + b + c + d + e + +- a + b + c + d + e + +1. a + b + c + d + e + +1. a + b + c + d + e + + +- a + b + c + d + e + +- a + b + c + d + e + +1. a + b + c + d + e + +1. a + b + c + d + e + + +- a + b + c + d + e + +- a + b + c + d + e + +1. a + b + c + d + e + +1. a + b + c + d + e +``` + +#### Fix HTML formatting broken if the beginning tag starts after a list item ([#7181](https://github.com/prettier/prettier/pull/7181) by [@sasurau4](https://github.com/sasurau4), [#7220](https://github.com/prettier/prettier/pull/7220) by [@sasurau4](https://github.com/sasurau4)) + +Previously, when Prettier format the html tag that starts after a list item, it would insert indent and break the relationship of open and close tag. Now, Prettier no longer change anything. + + +```md + +- A list item. +
Summary +

+ +- A list item. + +

+
+ +- A list item +
asdf
+ + +- A list item. + +
Summary +

+ +- A list item. + +

+
+ +- A list item +
asdf
+ + +- A list item. +
Summary +

+ +- A list item. + +

+
+ +- A list item +
asdf
+``` + +### MDX + +#### Fix JSX Fragment format incorrectly ([#6398](https://github.com/prettier/prettier/pull/6398) by [@JounQin](https://github.com/JounQin)) + +Previous versions format JSX Fragment incorrectly in mdx, this has been fixed in this version. + + +```md + +<> + test test + 123 + + +<> +test test + 123 + + +<> + test test + 123 +``` + +#### Fix MDX html parsing errors ([#6949](https://github.com/prettier/prettier/pull/6949) by [@Tigge](https://github.com/Tigge) & [@thorn0](https://github.com/thorn0)) + +MDX parsing for JSX failed when encountering JSX elements that where not +parsable as HTML. Such as `test` + + +````md + + +test + + +
+ hi + { hello } + { /* another comment */} +
+
+ + + +``` +SyntaxError: Unexpected closing tag "Tag". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (1:35) +> 1 | test + | ^ + 2 | + 3 | + 4 |
+``` + + + +test + + +
+ hi + {hello} + {/* another comment */} +
+
+ +```` + +### CLI + +#### Support file extensions `.cjs` and `.yaml.sed` ([#7210](https://github.com/prettier/prettier/pull/7210) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +```sh +# Prettier stable +$ prettier test.cjs +test.cjs[error] No parser could be inferred for file: test.cjs + +# Prettier master +$ prettier test.cjs +"use strict"; +console.log("Hello, World!"); +```