--- author: Ika (@ikatyang) authorURL: https://github.com/ikatyang title: "Prettier 1.14: YAML Support" --- This release adds YAML support, pragma (i.e. `/** @prettier */`) support for every language, and improves performance on large files. It also adds support for several new syntax features, and has a few formatting tweaks to make your code even prettier. ✨ ## Highlights ### YAML #### Support YAML ([#4563], [#4742], [#4773], [#4854] by [@ikatyang]) Prettier can now format YAML files! 🎉 The implementation is highly compliant with the [YAML spec](http://yaml.org/spec/), and backed by the excellent [`yaml`](https://github.com/eemeli/yaml) package thanks to [@eemeli]. A few highlights: ##### Word wrap Just like in Markdown, we’ll hard-wrap prose at 80-characters if it doesn’t affect the meaning of the file. Input: ```yaml > Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it’s my very good honour to meet you and you may call me V. ``` Output: (`--prose-wrap always`) ```yaml > Voilà! In view, a humble vaudevillian veteran cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valourous visitation of a bygone vexation stands vivified and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition! The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it’s my very good honour to meet you and you may call me V. ``` > Note: the [`proseWrap`](https://prettier.io/docs/en/options.html#prose-wrap) option is set to `preserve` by default so you’ll have to specify `always` or `never` to enable this feature. ##### Ignore a portion of the file If for some reason you don’t want to format a part of the YAML file, you can always put an ignore comment before it: ```yaml # prettier-ignore key : value hello: world ``` ### Front Matter #### Format YAML front matter ([#4773] by [@ikatyang]) Prettier can now format `---`-delimited YAML front matter in CSS and Markdown files: Input & Output (Prettier 1.13): ```markdown --- key : value --- # heading content ``` Output (Prettier 1.14): ```markdown --- key: value --- # heading content ``` ### Pragma #### Support `requirePragma`/`insertPragma` in every language ([#4688], [#4699], [#4713] by [@ikatyang]) Prettier 1.7.0 and 1.8.0 introduced two new options: [`--require-pragma`](https://prettier.io/docs/en/options.html#require-pragma) and [`--insert-pragma`](https://prettier.io/docs/en/options.html#insert-pragma). However, these options were only supported in a few languages. Now these options are available in every language, including YAML! - YAML ```yaml # @prettier key: value ``` - CSS/Less/SCSS ```css /** @prettier */ .class { display: none; } ``` - GraphQL ```gql # @prettier query Browse($offset: Int) { browse(offset: $offset) } ``` - Vue ```html ``` ### JavaScript #### Never inline decorators unless they’re lone parameter decorators ([#4830] by [@suchipi]) Previously, decorators were always inlined since MobX inlined them by convention, but reports from the community led us to discover that MobX is the only major library that follows this convention. Prettier now puts decorators on their own lines unless they’re parameter decorators. ```ts // Input @observer class OrderLine { @observable price: number = 0; @observable amount: number = 1; foo(@required name) { console.log(name); } } // Output (Prettier 1.13) @observer class OrderLine { @observable price: number = 0; @observable amount: number = 1; foo(@required name) { console.log(name); } } // Output (Prettier 1.14) @observer class OrderLine { @observable price: number = 0; @observable amount: number = 1; foo(@required name) { console.log(name); } } ``` #### Handle JSX whitespace separately from fbt whitespace ([#4717] by [@karl]) Previously, JSX whitespace was always preserved since Facebook has a custom translation pipeline (`fbt`) that uses JSX syntax but treats whitespace differently than regular JSX, which meant we couldn’t change JSX whitespace without breaking the Facebook codebase. In Prettier 1.14, we now detect Facebook `fbt` tags and handle whitespace for them differently from other JSX tags, improving the consistency across different but equivalent inputs. ```jsx // Input and Output from Prettier 1.13 first = (
Text
More text
And more
); second = (
Text
More text
And more
); third = (
Text
More text
And more
); // Output from Prettier 1.14 first = (
Text
More text
And more
); second = (
Text
More text
And more
); third = (
Text
More text
And more
); ``` When the text separating tags or expressions is just a single character we print the entire group on a single line where possible. ```jsx // Input and Output from Prettier 1.13 x = (
{hour}:{minute}:{second}
); x = (
{hour} : {minute} : {second}
); x = (
{hour}: {minute}: {second}
); // Output from Prettier 1.14 x = (
{hour}:{minute}:{second}
); x = (
{hour}:{minute}:{second}
); x = (
{hour}:{minute}:{second}
); ``` It also improves the output of edges cases like this: ```jsx // Input this_really_should_split_across_lines =
before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after
// Output (Prettier 1.13) this_really_should_split_across_lines = (
before{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{stuff}after{ stuff }after
); // Output (Prettier 1.14) this_really_should_split_across_lines = (
before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after
); ``` #### Break JSX in arrow functions in JSX expressions ([#4601] by [@duailibe]) In previous versions, JSX in arrow functions in JSX expressions followed the general fit-or-break rule, but it’s less readable when iterating over an array. Prettier 1.14 forces these arrow functions to break, improving readability. ```jsx // Input const UsersList = ({ users }) => (

Users list

) // Output (Prettier 1.13) const UsersList = ({ users }) => (

Users list

); // Output (Prettier 1.14) const UsersList = ({ users }) => (

Users list

); ``` ### TypeScript #### Support for TypeScript 3.0 ([#4625], [#4757] by [@ikatyang]) A few new features that include new syntax are added in the upcoming TypeScript 3.0: the [`unknown` type](https://github.com/Microsoft/TypeScript/pull/24439) and [tuples in rest parameters and spread expressions](https://github.com/Microsoft/TypeScript/pull/24897). Prettier 1.14 adds support for them so you can format them when TypeScript 3.0 is released. ```ts // UnknownType const json: unknown = JSON.parse(jsonText); // RestType type Foo = [string, number]; type Bar = [boolean, ...Foo]; // OptionalType type Baz = [string, number?]; ``` ### JSON #### Do not put values on a separate line from the key ([#4852] by [@ikatyang]) Putting long values on new rows is the core feature of Prettier, but we found that it doesn’t improve readability for objects with long string values inside JSON files. Prettier 1.14 will not move an object’s string value regardless if it fits the print width or not. ```json5 // Input { "description": "a long long long long long long long long long long long long long long long long long paragraph" } // Output (Prettier 1.13) { "description": "a long long long long long long long long long long long long long long long long long paragraph" } // Output (Prettier 1.14) { "description": "a long long long long long long long long long long long long long long long long long paragraph" } ``` ### Markdown #### Only align lists if they’re already aligned ([#4893] by [@ikatyang]) Previously, we always align lists for [better indenting experience and as a workaround for indented codeblock mis-parsing](https://prettier.io/blog/2018/02/26/1.11.0.html#respect-tabwidth-for-list-items-3990-by-ikatyang), but this introduced double spaces in front of ordered lists, which is not common in markdown. In Prettier 1.14, we only align lists in the following cases: - They’re already aligned. - There’re at least two spaces in front of the first list item. - There’s an indented codeblock inside of it. Input: ```md 1. 123 1. 123 --- 1. 123 1. 123 --- 11. 123 1. 123 --- 11. 123 1. 123 --- 1. 123 1. 123 ``` Output: (Prettier 1.13) ```md 1. 123 1. 123 --- 1. 123 1. 123 --- 11. 123 1. 123 --- 11. 123 1. 123 --- 1. 123 1. 123 ``` Output: (Prettier 1.14) ```md 1. 123 1. 123 --- 1. 123 1. 123 --- 11. 123 1. 123 --- 11. 123 1. 123 --- 1. 123 1. 123 ``` ### Performance #### Performance improvement on big files ([#4790], [#4848] by [@sompylasar]) The core feature of Prettier is to wrap lines when they go past the print width, and to do this we need to calculate the visual width of every character. The easiest way to count them is by using JavaScript’s `String#length` property but some non-ASCII characters like CJK characters have widths larger than a Latin character. As a workaround, we replaced those 2-char-wide characters with 2 spaces before calculating the string’s length. This works fine but it also slows down Prettier because we have to run the replacement on every token. In Prettier 1.14, we check if the string contains only ASCII characters so we don’t need to perform unnecessary string replacement. This results in a **20% speed-up** on large files. ## Other changes ### API/CLI #### Support relative paths for `plugins` and `pluginSearchDirs` in config files ([#4667] by [@ikatyang]) In Prettier 1.13, we introduced a new `pluginSearchDirs` option that changes where Prettier looks for plugins. It worked well when specified in the CLI since it was always relative to the current directory, but relative paths didn’t work in config files. In Prettier 1.14, relative paths for `pluginSearchDirs` and `plugins` in config files are now supported. #### Do not throw error if `prettier` installed in a directory not named `prettier` ([#4706] by [@asottile]) We added support for globally installed plugins in Prettier 1.13 by searching up the directory tree to find the nearest `node_modules` from `prettier`. We assumed that there would always be a `prettier` directory which caused Prettier to crash if it was in a differently-named directory. We changed our searching logic in Prettier 1.14 so you should now be able to rename the `prettier` directory if you need to (for example if publishing a fork to npm). #### Support `filepath` in browser ([#4721] by [@ikatyang]) In Prettier 1.13, we added first-class support for running Prettier in the browser, but the only way to choose which parser to use was via the `parser` option. Prettier 1.14 adds support for the `filepath` option in the browser API, which will allow Prettier to infer which parser to use, just like the it can with the Node.js API. This should be especially useful for web editor applications! #### Expose `isPreviousLineEmpty` to plugins ([#4748] by [@warrenseine]) Previously, we exposed `isNextLineEmpty` to plugins but not `isPreviousLineEmpty`. Prettier 1.14 exposes it, because it can be useful for some scenarios like directives in C#. ### JavaScript #### Support BigInt literals ([#4697] by [@ikatyang]) [BigInt](https://github.com/tc39/proposal-bigint) literals are now supported in the default `babylon` parser. ```js const bigInt = 1n; ``` #### Support `throw` expressions ([#4695] by [@VojtechStep]) [Throw expressions](https://github.com/tc39/proposal-throw-expressions) are now supported in the default `babylon` parser. ```js const assert = x => x || throw new Error('...'); ``` #### Always expand the first argument if the second argument is also a call expression ([#4657] by [@duailibe]) Previously, we had a special case to not break function calls if there were only 2 parameters passed and the first parameter was a function. This worked well, but if the second parameter was also a function, it didn’t look very good. ```js // Input somePromise.then((args) => { this.props.receiveFavoritesActions(id, [].concat(...args)); }, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`)); // Output (Prettier 1.13) somePromise.then(args => { this.props.receiveFavoritesActions(id, [].concat(...args)); }, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`)); // Output (Prettier 1.14) somePromise.then( args => { this.props.receiveFavoritesActions(id, [].concat(...args)); }, ({ isCanceled }) => !isCanceled && logger.warn(`Error getting actions for the product: ${id}`) ); ``` #### Add parens for await in bind ([#4778] by [@ikatyang]) Previously, Prettier wrongly removed the necessary parentheses for `await` in the experimental bind syntax, causing its meaning to be change. Prettier 1.14 now preserves the parentheses correctly. ```js // Input const doBothThings = async () => { const request = doAsyncThing(); return (await request)::doSyncThing(); }; // Output (Prettier 1.13) const doBothThings = async () => { const request = doAsyncThing(); return await request::doSyncThing(); // means `await (request::doSyncThing)` }; // Output (Prettier 1.14) const doBothThings = async () => { const request = doAsyncThing(); return (await request)::doSyncThing(); }; ``` #### Allow top level `super` and `await` ([#4823] by [@ikatyang]) `super` and `await` are not allowed to be in places other than classes and async functions, respectively, but our [range format](https://prettier.io/docs/en/options.html#range) option didn’t quite work properly when selecting the contents of a function. Prettier 1.14 allows them to be everywhere. ```js super(); await doSomething(); ``` #### Blacklist `this` and `super` in functional composition heuristics ([#4836] by [@princed]) In Prettier 1.13, we improved the formatting for functional composition functions (e.g., `pipe`, `compose`, etc.) by putting their parameters on their own line, but this introduced false positives for functions with the same name in classes. Prettier 1.14 blacklists `this` and `super` in functional composition heuristics. ```js // Input class X { x() { this.compose(a(), b); super.compose(a(), b); } } // Output (Prettier 1.13) class X { x() { this.compose( a(), b ); super.compose( a(), b ); } } // Output (Prettier 1.14) class X { x() { this.compose(a(), b); super.compose(a(), b); } } ``` ### TypeScript #### Support `import.meta` ([#4762] by [@ikatyang]) In Prettier 1.13, the version of the TypeScript parser we used did not support parsing `import.meta` syntax. We updated our TypeScript parser in Prettier 1.14 so they are now parsed and formatted correctly. ```js console.log(import.meta.url); ``` #### Optional property with StringLiteral key in class ([#4762] by [@ikatyang]) In the prior version, the `?` in an optional property with a string literal as the key was wrongly removed. We fixed this bug in Prettier 1.14 so it won’t be removed. ```ts // Input export class ClassExample { "a-prop"?: boolean; } // Output (Prettier 1.13) export class ClassExample { "a-prop": boolean; } // Output (Prettier 1.14) export class ClassExample { "a-prop"?: boolean; } ``` #### Throw error on multiple super classes in class ([#4762] by [@ikatyang]) Classes are only allowed to have one parent class but the TypeScript AST allows for multiple since the `extends` clause has the same structure internally as the `implements` clause. Previously, any extra super classes were silently dropped during printing, which may have caused confusion after formatting. In Prettier 1.14, they are now marked as syntax errors instead. ```ts // Input class Foo extends BarComponent, BazService, QuuxProvider {} // Output (Prettier 1.13) class Foo extends BarComponent {} // Output (Prettier 1.14) /* SyntaxError: Classes can only extend a single class. */ ``` #### Support JSX spread child ([#4885] by [@ikatyang]) Previously, the `...` in children spread in JSX expressions were wrongly removed. We fixed this issue in Prettier 1.14. ```tsx // Input const x =
{...[0]}
// Output (Prettier 1.13) const x =
{[0]}
; // Output (Prettier 1.14) const x =
{...[0]}
; ``` ### Flow #### Support `.js.flow` extension ([#4777] by [@ikatyang]) [`.js.flow`](https://flow.org/en/docs/libdefs/creation/#toc-declaring-a-module) is the extension for Flow declaration files but previously we didn’t recognize it. In Prettier 1.14, they should be picked up automatically so you don’t need to add overrides for them in config files. ### CSS/Less/SCSS #### Handle newline between front-matter and comment correctly ([#4701] by [@evilebottnawi]) Multiple newlines between front matter and a CSS comment were replaced with a space in Prettier 1.13. In Prettier 1.14, we print a newline between them instead. ```css /* Input */ --- key: value --- /* comment */ .class { display: none; } /* Output (Prettier 1.13) */ --- key: value --- /* comment */ .class { display: none; } /* Output (Prettier 1.14) */ --- key: value --- /* comment */ .class { display: none; } ``` #### Support at-rule ends with right curly bracket ([#4733] by [@davidgomes]) In the prior version, at-rules that ended with `}` were not parsed correctly. Prettier 1.14 now correctly recognizes and formats them. ```scss /* Input */ @mixin placeholder { &::placeholder {@content} } /* Output (Prettier 1.13) */ /* SyntaxError: CssSyntaxError Unclosed block */ /* Output (Prettier 1.14) */ @mixin placeholder { &::placeholder { @content; } } ``` ### Markdown #### Preserve email autolink ([#4740] by [@ikatyang]) Autolinks are formatted as their url in the prior version, which is fine. But there’s a special case for email links that they’ll be resolved as `mailto:` links. In Prettier 1.14, email autolinks are preserved. ```md ``` #### Do not require space after markdown block language name ([#4783] by [@kachkaev]) In Prettier 1.12, we added the support for fenced codeblock lang followed by attributes, which requires them to be separated by whitespaces. But this introduced the inconsistency for codeblock highlighting in Atom that codeblocks are highlighted but we do not format them. We updated our detection logic in Prettier 1.14 so they should behave the same now. ````md ```js{something=something} const x = 1; ``` ```js{something=something} const x = 1; ``` ```js{something=something} const x = 1; ``` ```` #### Use language aliases to find parser for markdown codeblocks ([#4734] by [@ikatyang]) Previously, we used the language `name` and `extensions` to determine which parser to use for codeblock formatting, but we found that it’s impossible to format `JSON with Comments` codeblocks and keep syntax highlighter working at the same time since they share the same `.json` extension with `JSON` and the comment syntax highlighting is only available in `JSON5`. We added the support for using the language `aliases` to find parser in Prettier 1.14 so you should be able to use `jsonc` to format and trigger syntax highlighting for `JSON with Comments` codeblocks. ````md ```jsonc // comment {"a":1} ``` ```jsonc // comment {"a":1} ``` ```jsonc // comment { "a": 1 } ``` ```` #### Preserve entity for encoded character if its code point is greater than U+FFFF ([#4832] by [@ikatyang]) The markdown parser we use (`remark`) parses every encoded character into a single AST node so that we’re able to restore the encoded character by detecting if the value in the AST node is in length of 1. But there’s an exception that a single character can be in length of 2 if its code point is greater than 0xffff since JavaScript uses UTF-16 (2 bytes) to encode strings. Prettier 1.14 correctly recognizes these characters so they won’t be transformed into the literal character. ````md 😉 😉 😉 ```` ### Vue #### Support range format for Vue files ([#4868] by [@ikatyang]) Previously, [range formatting](https://prettier.io/docs/en/options.html#range) was not available in Vue, but Prettier 1.14 adds support for it. ### GraphQL #### Preserve linebreak in non-block stringValue ([#4808] by [@ikatyang]) Non-block string values are only allowed to be in a single line but Prettier 1.13 wrongly transformed the escaped `\n` into a real newline. Prettier 1.14 now correctly prints `\n`. ```gql # Input { foo(input: {multiline: "ab\ncd"}) { id } } # Output (Prettier 1.13) { foo(input: { multiline: "ab cd" }) { id } } # Output (Prettier 1.14) { foo(input: { multiline: "ab\ncd" }) { id } } ``` [@asottile]: https://github.com/asottile [@davidgomes]: https://github.com/davidgomes [@duailibe]: https://github.com/duailibe [@eemeli]: https://github.com/eemeli [@evilebottnawi]: https://github.com/evilebottnawi [@ikatyang]: https://github.com/ikatyang [@kachkaev]: https://github.com/kachkaev [@karl]: https://github.com/karl [@princed]: https://github.com/princed [@sompylasar]: https://github.com/sompylasar [@suchipi]: https://github.com/@suchipi [@vojtechstep]: https://github.com/VojtechStep [@warrenseine]: https://github.com/warrenseine [#4563]: https://github.com/prettier/prettier/pull/4563 [#4601]: https://github.com/prettier/prettier/pull/4601 [#4625]: https://github.com/prettier/prettier/pull/4625 [#4657]: https://github.com/prettier/prettier/pull/4657 [#4667]: https://github.com/prettier/prettier/pull/4667 [#4688]: https://github.com/prettier/prettier/pull/4688 [#4695]: https://github.com/prettier/prettier/pull/4695 [#4697]: https://github.com/prettier/prettier/pull/4697 [#4699]: https://github.com/prettier/prettier/pull/4699 [#4701]: https://github.com/prettier/prettier/pull/4701 [#4706]: https://github.com/prettier/prettier/pull/4706 [#4713]: https://github.com/prettier/prettier/pull/4713 [#4717]: https://github.com/prettier/prettier/pull/4717 [#4721]: https://github.com/prettier/prettier/pull/4721 [#4733]: https://github.com/prettier/prettier/pull/4733 [#4734]: https://github.com/prettier/prettier/pull/4734 [#4740]: https://github.com/prettier/prettier/pull/4740 [#4742]: https://github.com/prettier/prettier/pull/4742 [#4748]: https://github.com/prettier/prettier/pull/4748 [#4757]: https://github.com/prettier/prettier/pull/4757 [#4762]: https://github.com/prettier/prettier/pull/4762 [#4773]: https://github.com/prettier/prettier/pull/4773 [#4777]: https://github.com/prettier/prettier/pull/4777 [#4778]: https://github.com/prettier/prettier/pull/4778 [#4783]: https://github.com/prettier/prettier/pull/4783 [#4790]: https://github.com/prettier/prettier/pull/4790 [#4808]: https://github.com/prettier/prettier/pull/4808 [#4823]: https://github.com/prettier/prettier/pull/4823 [#4830]: https://github.com/prettier/prettier/pull/4830 [#4832]: https://github.com/prettier/prettier/pull/4832 [#4836]: https://github.com/prettier/prettier/pull/4836 [#4848]: https://github.com/prettier/prettier/pull/4848 [#4852]: https://github.com/prettier/prettier/pull/4852 [#4854]: https://github.com/prettier/prettier/pull/4854 [#4868]: https://github.com/prettier/prettier/pull/4868 [#4885]: https://github.com/prettier/prettier/pull/4885 [#4893]: https://github.com/prettier/prettier/pull/4893