diff --git a/changelog_unreleased/api/13130.md b/changelog_unreleased/api/13130.md index d59d818a3..844b13bdf 100644 --- a/changelog_unreleased/api/13130.md +++ b/changelog_unreleased/api/13130.md @@ -1,4 +1,4 @@ -#### Support config files in ESM (#13130 by @fisker) +#### [HIGHLIGHT]Support config files in ESM (#13130 by @fisker) Config files in ESM are supported, supported config file names: diff --git a/changelog_unreleased/api/13397.md b/changelog_unreleased/api/13397.md index 296e81af6..e033e43e9 100644 --- a/changelog_unreleased/api/13397.md +++ b/changelog_unreleased/api/13397.md @@ -11,9 +11,6 @@ function print(path, print) { - return path.map(print, "values"); -+ return path.map((childPath) => { -+ const value = childPath.getValue(); -+ return value?.type ? print() : String(value); -+ }, "values"); ++ return path.map(({node}) => (node?.type ? print() : String(node)), "values"); } ``` diff --git a/changelog_unreleased/api/14759.md b/changelog_unreleased/api/14759.md index 95059b768..5fb1d61f9 100644 --- a/changelog_unreleased/api/14759.md +++ b/changelog_unreleased/api/14759.md @@ -1,4 +1,4 @@ -#### [Breaking] plugin search feature has been removed (#14759 by @fisker) +#### [BREAKING] plugin search feature has been removed (#14759 by @fisker) The plugin auto search feature didn't work well when using pnpm, and cause slowness. diff --git a/changelog_unreleased/blog-post-intro.md b/changelog_unreleased/blog-post-intro.md new file mode 100644 index 000000000..60d0852d8 --- /dev/null +++ b/changelog_unreleased/blog-post-intro.md @@ -0,0 +1,17 @@ +--- +author: "Sosuke Suzuki (@sosukesuzuki)" +authorURL: "https://github.com/sosukesuzuki" +title: "Prettier 3.0: Hello, ECMAScript Modules!" +--- + +We are excited to announce the release of the new version of Prettier! + +We have made the migration to using ECMAScript Modules for all our source code. This change has significantly improved the development experience for the Prettier team. Please rest assured that when using Prettier as a library, you can still use it as CommonJS as well. + +This update comes with several breaking changes. One notable example is the alteration in markdown formatting - spaces are no longer inserted between Latin characters and Chinese or Japanese characters. We'd like to extend our gratitude to [Tatsunori Uchino](https://github.com/tats-u), who has made significant contributions to Prettier over the past year, particularly with this feature. Additionally, the default value of `trailingComma` has been changed to `"all"`. + +Another important change in this release is the significant overhaul of the plugin interface. Prettier now supports plugins written using ECMAScript Modules and async parsers. If you're a plugin developer, please exercise caution while updating. You can find [the migration guide](https://github.com/prettier/prettier/wiki/How-to-migrate-my-plugin-to-support-Prettier-v3%3F) here. As always, we welcome bug reports and feedback! + +This release also includes numerous formatting improvements and bug fixes. + +If you appreciate Prettier and would like to support our work, please consider sponsoring us directly via [our OpenCollective](https://opencollective.com/prettier) or by sponsoring the projects we depend on, such as [typescript-eslint](https://opencollective.com/typescript-eslint), [remark](https://opencollective.com/unified), and [Babel](https://opencollective.com/babel). Thank you for your continued support! diff --git a/changelog_unreleased/cli/14731.md b/changelog_unreleased/cli/14731.md index 2d7b11ef5..7f81bafca 100644 --- a/changelog_unreleased/cli/14731.md +++ b/changelog_unreleased/cli/14731.md @@ -1,4 +1,4 @@ -#### [Breaking] Ignore `.gitignore`d files by default (#14731 by @fisker) +#### [BREAKING] Ignore `.gitignore`d files by default (#14731 by @fisker) Prettier ignores files ignored by `.gitignore` by default. If you want the old behavior(only ignore files ignored by `.prettierignore`), use diff --git a/changelog_unreleased/graphql/12835.md b/changelog_unreleased/graphql/12835.md index c57b99823..f0718b6db 100644 --- a/changelog_unreleased/graphql/12835.md +++ b/changelog_unreleased/graphql/12835.md @@ -1,4 +1,4 @@ -#### [Breaking] Drop support for "comma separated interfaces" syntax (#12835 by @fisker) +#### [BREAKING] Drop support for "comma separated interfaces" syntax (#12835 by @fisker) ```graphql diff --git a/cspell.json b/cspell.json index 35715fc25..67866f185 100644 --- a/cspell.json +++ b/cspell.json @@ -322,6 +322,7 @@ "supertypes", "Supprimer", "swcrc", + "Tatsunori", "templating", "tempy", "testname", @@ -341,6 +342,7 @@ "typecasted", "typecheck", "typeof", + "Uchino", "Ubie", "Umidbek", "unaries", diff --git a/website/blog/2023-07-05-3.1.0.md b/website/blog/2023-07-05-3.1.0.md new file mode 100644 index 000000000..224330b44 --- /dev/null +++ b/website/blog/2023-07-05-3.1.0.md @@ -0,0 +1,2149 @@ +--- +author: "Sosuke Suzuki (@sosukesuzuki)" +authorURL: "https://github.com/sosukesuzuki" +title: "Prettier 3.0: Hello, ECMAScript Modules!" +--- + +We are excited to announce the release of the new version of Prettier! + +We have made the migration to using ECMAScript Modules for all our source code. This change has significantly improved the development experience for the Prettier team. Please rest assured that when using Prettier as a library, you can still use it as CommonJS as well. + +This update comes with several breaking changes. One notable example is the alteration in markdown formatting - spaces are no longer inserted between Latin characters and Chinese or Japanese characters. We'd like to extend our gratitude to [Tatsunori Uchino](https://github.com/tats-u), who has made significant contributions to Prettier over the past year, particularly with this feature. Additionally, the default value of `trailingComma` has been changed to `"all"`. + +Another important change in this release is the significant overhaul of the plugin interface. Prettier now supports plugins written using ECMAScript Modules and async parsers. If you're a plugin developer, please exercise caution while updating. You can find [the migration guide](https://github.com/prettier/prettier/wiki/How-to-migrate-my-plugin-to-support-Prettier-v3%3F) here. As always, we welcome bug reports and feedback! + +This release also includes numerous formatting improvements and bug fixes. + +If you appreciate Prettier and would like to support our work, please consider sponsoring us directly via [our OpenCollective](https://opencollective.com/prettier) or by sponsoring the projects we depend on, such as [typescript-eslint](https://opencollective.com/typescript-eslint), [remark](https://opencollective.com/unified), and [Babel](https://opencollective.com/babel). Thank you for your continued support! + + + +## Highlights + +### Markdown + +#### Improve handling of whitespace for Chinese, Japanese, and Korean ([#11597](https://github.com/prettier/prettier/pull/11597) by [@tats-u](https://github.com/tats-u)) + +##### Stop inserting spaces between Chinese or Japanese and Western characters + +Previously, Prettier would insert spaces between Chinese or Japanese and Western characters (letters and digits). While some people prefer this style, it isn’t standard, and is in fact contrary to official guidelines. Please see [here](https://github.com/tats-u/prettier-plugin-md-nocjsp#why-this-plugin-is-needed) for more details. We decided it’s not Prettier’s job to enforce a particular style in this case, so spaces aren’t inserted anymore, while existing ones are preserved. If you need a tool for enforcing spacing style, consider [textlint-ja](https://github.com/textlint-ja/textlint-rule-preset-ja-spacing/tree/master/packages/textlint-rule-ja-space-between-half-and-full-width) or [lint-md](https://github.com/lint-md/lint-md) (rules `space-round-alphabet` and `space-round-number`). + +The tricky part of this change were ambiguous line breaks between Chinese or Japanese and Western characters. When Prettier unwraps text, it needs to decide whether such a line break should be simply removed or replaced with a space. For that Prettier examines the surrounding text and infers the preferred style. + + +```markdown + +漢字 +Alphabetsひらがな12345カタカナ67890 + +漢字 Alphabets ひらがな 12345 カタカナ 67890 + + +漢字 Alphabets ひらがな 12345 カタカナ 67890 + +漢字 Alphabets ひらがな 12345 カタカナ 67890 + + +漢字Alphabetsひらがな12345カタカナ67890 + +漢字 Alphabets ひらがな 12345 カタカナ 67890 +``` + +##### Comply to line breaking rules in Chinese and Japanese + +There are rules that prohibit certain characters from appearing at the beginning or the end of a line in [Chinese](https://www.w3.org/TR/clreq/#prohibition_rules_for_line_start_end) and [Japanese](https://www.w3.org/TR/jlreq/#characters_not_starting_a_line). E.g., full stop characters `。`, `.`, and `.` shouldn’t start a line whereas `(` shouldn’t end a line. Prettier now follows these rules when it wraps text, that is when `proseWrap` is set to `always`. + + +```markdown + +HTCPCPのエラー418は、ティーポットにコーヒーを淹(い)れさせようとしたときに返されるステータスコードだ。 + + +HTCPCP の +エラー +418 は、 +ティーポ +ットにコ +ーヒーを +淹(い) +れさせよ +うとした +ときに返 +されるス +テータス +コードだ +。 + + +HTCPCPの +エラー +418は、 +ティー +ポットに +コーヒー +を淹 +(い)れ +させよう +としたと +きに返さ +れるス +テータス +コード +だ。 +``` + +##### Do not break lines inside Korean words + +Korean uses spaces to divide words, and an inappropriate division may change the meaning of a sentence: + +- `노래를 못해요.`: I’m not good at singing. +- `노래를 못 해요.`: I can’t sing (for some reason). + +Previously, when `proseWrap` was set to `always`, successive Hangul characters could get split by a line break, which could later be converted to a space when the document is edited and reformatted. This doesn’t happen anymore. Korean text is now wrapped like English. + + +```markdown + +노래를 못해요. + + +노래를 못 +해요. + + +노래를 못 해요. + + +노래를 +못해요. + + +노래를 못해요. +``` + +A line break between Hangul and non-Hangul letters and digits is converted to a space when Prettier unwraps the text. Consider this example: + +> 3분 기다려 주지. + +In this sentence, if you break the line between “3” and “분”, a space will be inserted there when the text gets unwrapped. + +### API + +#### Support plugins with async parsers ([#12748](https://github.com/prettier/prettier/pull/12748) by [@fisker](https://github.com/fisker), [#13211](https://github.com/prettier/prettier/pull/13211) by [@thorn0](https://github.com/thorn0) and [@fisker](https://github.com/fisker)) + +[`parse` function](https://prettier.io/docs/en/plugins.html#parsers) in a plugin can return a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) now. + +In order to support async parsers for embedded languages, we had to introduce a breaking change to the plugin API. Namely, the `embed` method of a printer has now to match a completely new signature, incompatible with previous versions. If you're a plugin author and your plugins don't define `embed`, you have nothing to worry about, otherwise see the [docs](/docs/plugins.html#optional-embed) for details. + +Also, the `preprocess` method of a printer can return a promise now. + +#### Support config files in ESM ([#13130](https://github.com/prettier/prettier/pull/13130) by [@fisker](https://github.com/fisker)) + +Config files in ESM are supported, supported config file names: + +- `prettier.config.js` (in place with `{"type": "module"}` in `package.json`) +- `.prettierrc.js` (same as above) +- `prettier.config.mjs` +- `.prettierrc.mjs`. + +```js +export default { + trailingComma: "es5", + tabWidth: 4, + semi: false, + singleQuote: true, +}; +``` + +**[Shareable config package](https://prettier.io/docs/en/configuration.html#sharing-configurations) can also be a pure ESM package.** + +## Breaking Changes + +### JavaScript + +#### Change the default value for `trailingComma` to `all` ([#11479](https://github.com/prettier/prettier/pull/11479) by [@fisker](https://github.com/fisker), [#13143](https://github.com/prettier/prettier/pull/13143) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +Since version 2.0. we've changed the default value for `trailingComma` to `es5`. + +[Internet Explorer, the last browser to not allow trailing commas in function calls, has been unsupported on June 15, 2022.](https://docs.microsoft.com/en-us/lifecycle/announcements/internet-explorer-11-end-of-support) Accordingly, change the default value for `trailingComma` to `all`. + +If the old behavior is still preferred, please configure Prettier with `{ "trailingComma": "es5" }`. + +#### Remove Flow syntax support from `babel` parser ([#14314](https://github.com/prettier/prettier/pull/14314) by [@fisker](https://github.com/fisker), [@thorn0](https://github.com/thorn0)) + +For historical reasons, Prettier used to recognize Flow syntax in JS files when the `parser` option was set to `babel` even if the file didn't include the `@flow` pragma. This support was limited and bad for performance, so it has been removed in Prettier 3.1. Prettier with the `babel` parser still automatically switches to the Flow syntax if it finds the `@flow` pragma or the file has the `.js.flow` extension. + +### Flow + +#### Remove support for Flow comments ([#13687](https://github.com/prettier/prettier/pull/13687), [#13703](https://github.com/prettier/prettier/pull/13703) by [@thorn0](https://github.com/thorn0)) + +Being a kind of preprocessor, [Flow comments](https://flow.org/blog/2015/02/20/Flow-Comments/) AKA [comment types](https://flow.org/en/docs/types/comments/) are processed on the token level and can't be represented in an AST in the general case. Flow builds the AST as if these special comment tokens didn't exist. Example: + + +```js +/*:: if */ (x) + y; +``` + +This is parsed as `if (x) +y;` by Flow and as `x + y;` by JS parsers that don't support Flow. + +Previously, for some special cases, Prettier tried to detect that this syntax was used and to preserve it. As an attempt to solve an unsolvable problem, this limited support was fragile and riddled with bugs, so it has been removed. Now if the `parser` option is set to `flow` or `babel-flow`, Flow comments will be parsed and reprinted like normal code. If a parser that doesn't support Flow is used, they will be treated like usual comments. + + +```js +// Input +let a /*: foo */ = b; + +// Prettier 2.8 +let a /*: foo */ = b; + +// Prettier 3.1 with --parser flow +let a: foo = b; + +// Prettier 3.1 with --parser babel +let a /*: foo */ = b; +``` + +#### Print trailing comma in type parameters and tuple types when `--trailing-comma=es5` ([#14086](https://github.com/prettier/prettier/pull/14086), [#14085](https://github.com/prettier/prettier/pull/14085) by [@fisker](https://github.com/fisker)) + + +```js +// Input +type Foo = [ + { + from: string, + to: string, + }, // <- 1 +]; +type Foo = Promise< + | { ok: true, bar: string, baz: SomeOtherLongType } + | { ok: false, bar: SomeOtherLongType }, // <- 2 +>; + +// Prettier 2.8 +type Foo = [ + { + from: string, + to: string, + } // <- 1 +]; +type Foo = Promise< + | { ok: true, bar: string, baz: SomeOtherLongType } + | { ok: false, bar: SomeOtherLongType } // <- 2 +>; + +// Prettier 3.1 +type Foo = [ + { + from: string, + to: string, + }, // <- 1 +]; +type Foo = Promise< + | { ok: true, bar: string, baz: SomeOtherLongType } + | { ok: false, bar: SomeOtherLongType }, // <- 2 +>; +``` + +### CSS + +#### Add the pure `css` parser ([#7933](https://github.com/prettier/prettier/pull/7933), [#9092](https://github.com/prettier/prettier/pull/9092), [#9093](https://github.com/prettier/prettier/pull/9093) by [@fisker](https://github.com/fisker)) + +Previously, when `--parser=css` was passed, Prettier tried to parse the content using `postcss-scss` and `postcss-less`. This caused confusion, and made syntax errors difficult to spot. Now `--parser=css` works only with the vanilla CSS syntax. + +_If you use `parser="css"` for your `.less`/`.scss` files, update it to the correct parser or remove the `parser` option to let Prettier auto-detect the parser by the file extension._ + + +```less +/* Input */ +/* Less Syntax with `--parser=css` */ +a {.bordered();} + +/* Prettier 2.8 */ +/* Less Syntax with `--parser=css` */ +a { + .bordered(); +} + +/* Prettier 3.1 */ +SyntaxError: (postcss) CssSyntaxError Unknown word (2:4) + 1 | /* Less Syntax with `--parser=css` */ +> 2 | a {.bordered();} +``` + + +```scss +/* Input */ +/* Scss Syntax with `--parser=css` */ +::before {content: #{$foo}} + +/* Prettier 2.8 */ +/* Scss Syntax with `--parser=css` */ +::before { + content: #{$foo}; +} + +/* Prettier 3.1 */ +SyntaxError: (postcss) CssSyntaxError Unknown word (2:22) + 1 | /* Scss Syntax with `--parser=css` */ +> 2 | ::before {content: #{$foo}} +``` + +### GraphQL + +#### Drop support for "comma separated interfaces" syntax ([#12835](https://github.com/prettier/prettier/pull/12835) by [@fisker](https://github.com/fisker)) + + +```graphql +# Input +type Type1 implements A, B {a: a} + +# Prettier 2.8 +type Type1 implements A, B { + a: a +} + +# Prettier 3.1 +SyntaxError: Syntax Error: Unexpected Name "B". (1:26) +> 1 | type Type1 implements A, B {a: a} +``` + +### API + +#### Drop support for Node.js 10 and 12 ([#11830](https://github.com/prettier/prettier/pull/11830) by [@fisker](https://github.com/fisker), [#13118](https://github.com/prettier/prettier/pull/13118) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +The minimal required Node.js version is v14 + +#### Change public APIs to asynchronous ([#12574](https://github.com/prettier/prettier/pull/12574), [#12788](https://github.com/prettier/prettier/pull/12788), [#12790](https://github.com/prettier/prettier/pull/12790), [#13265](https://github.com/prettier/prettier/pull/13265) by [@fisker](https://github.com/fisker)) + +- `prettier.format()` returns `Promise` +- `prettier.formatWithCursor()` returns `Promise<{formatted: string, cursorOffset: number}>` +- `prettier.formatAST()` returns `Promise` +- `prettier.check()` returns `Promise` +- `prettier.getSupportInfo()` returns `Promise` +- `prettier.clearConfigCache()` returns `Promise` +- `prettier.resolveConfig.sync` is removed +- `prettier.resolveConfigFile.sync` is removed +- `prettier.getFileInfo.sync` is removed + +If you still need sync APIs, you can try [`@prettier/sync`](https://github.com/prettier/prettier-synchronized) + +#### Npm package file structures changed ([#12740](https://github.com/prettier/prettier/pull/12740) by [@fisker](https://github.com/fisker), [#13530](https://github.com/prettier/prettier/pull/13530) by [@fisker](https://github.com/fisker), [#14570](https://github.com/prettier/prettier/pull/14570) by [@fisker](https://github.com/fisker)) + +File structures changes: + +- `bin-prettier.js` -> `bin/prettier.cjs` +- `esm/standalone.mjs` -> `standalone.mjs` +- `esm/parser-angular.mjs` -> `plugins/angular.mjs` +- `parser-angular.js` -> `plugins/angular.js` +- `esm/parser-babel.mjs` -> `plugins/babel.mjs` +- `parser-babel.js` -> `plugins/babel.js` +- `esm/parser-espree.mjs` -> `plugins/acorn-and-espree.mjs` +- `parser-espree.js` -> `plugins/acorn.js`\ + global object renamed `prettierPlugins.espree` -> `prettierPlugins.acorn` +- `esm/parser-flow.mjs` -> `plugins/flow.mjs` +- `parser-flow.js` -> `plugins/flow.js` +- `esm/parser-glimmer.mjs` -> `plugins/glimmer.mjs` +- `parser-glimmer.js` -> `plugins/glimmer.js` +- `esm/parser-graphql.mjs` -> `plugins/graphql.mjs` +- `parser-graphql.js` -> `plugins/graphql.js` +- `esm/parser-html.mjs` -> `plugins/html.mjs` +- `parser-html.js` -> `plugins/html.js` +- `esm/parser-markdown.mjs` -> `plugins/markdown.mjs` +- `parser-markdown.js` -> `plugins/markdown.js` +- `esm/parser-meriyah.mjs` -> `plugins/meriyah.mjs` +- `parser-meriyah.js` -> `plugins/meriyah.js` +- `esm/parser-postcss.mjs` -> `plugins/postcss.mjs` +- `parser-postcss.js` -> `plugins/postcss.js` +- `esm/parser-typescript.mjs` -> `plugins/typescript.mjs` +- `parser-typescript.js` -> `plugins/typescript.js` +- `esm/parser-yaml.mjs` -> `plugins/yaml.mjs` +- `parser-yaml.js` -> `plugins/yaml.js` + +Check full list on . + +A new plugin has been added: + +- `plugins/estree.mjs` (ESM version) +- `plugins/estree.js` (UMD version) + +If you use standalone version, this plugin should be loaded when printing JavaScript, TypeScript, Flow, or JSON. + +```diff +import { format } from "prettier/standalone"; +- import prettierPluginBabel from "prettier/parser-babel"; ++ import * as prettierPluginBabel from "prettier/plugins/babel"; ++ import * as prettierPluginEstree from "prettier/plugins/estree"; + +console.log( +- format(code, { ++ await format(code, { + parser: "babel", +- plugins: [prettierPluginBabel], ++ plugins: [prettierPluginBabel, prettierPluginEstree], + }) +); +``` + +```diff +- node ./node_modules/prettier/bin-prettier.js . --write ++ node ./node_modules/prettier/bin/prettier.cjs . --write +``` + +#### Support plugins in ESM ([#13201](https://github.com/prettier/prettier/pull/13201) by [@fisker](https://github.com/fisker)) + +Since v3.0.0, we load plugins via `import()` instead of `require()`, plugins can be ESM modules now. + +If you use `--plugin` by directory path, or file path without extensions, the plugin may not able to load. + +```diff +- prettier . --plugin=path/to/my-plugin-directory ++ prettier . --plugin=path/to/my-plugin-directory/index.js +``` + +```diff +- prettier . --plugin=path/to/my-plugin-file ++ prettier . --plugin=path/to/my-plugin-file.js +``` + +#### Update `prettier.doc` ([#13203](https://github.com/prettier/prettier/pull/13203), [#14456](https://github.com/prettier/prettier/pull/14456) by [@fisker](https://github.com/fisker)) + +`prettier.doc.builders.concat` [was deprecated in v2.3.0](https://prettier.io/blog/2021/05/09/2.3.0.html#use-arrays-instead-of-concat-9733httpsgithubcomprettierprettierpull9733-by-fiskerhttpsgithubcomfisker-thorn0httpsgithubcomthorn0), now it's removed. + +The following apis are never documented, they mean to only use internally, now they are removed. + +- `prettier.doc.utils.getDocParts` +- `prettier.doc.utils.propagateBreaks` +- `prettier.doc.utils.cleanDoc` +- `prettier.doc.utils.getDocType` +- `prettier.doc.debug.printDocToDebug` + +#### `textToDoc` trims trailing hard lines ([#13220](https://github.com/prettier/prettier/pull/13220) by [@fisker](https://github.com/fisker)) + +Previously, in all core languages, after embedded code printed to `Doc`, we call `prettier.doc.utils.stripTrailingHardline()` to remove the trailing hard lines. + +We believe make `textToDoc` return docs without trailing hard lines makes the plugins easier to do `embed` print. + +#### Removed support for custom parser api ([#13250](https://github.com/prettier/prettier/pull/13250) by [@fisker](https://github.com/fisker) and [@thorn0](https://github.com/thorn0)) + +Before [plugins](/docs/en/plugins.html) were a thing, Prettier had a similar but more limited feature called custom parsers. It’s been removed in v3.0.0 as its functionality was a subset of what the Plugin API did. If you used it, please check [how to migrate](/docs/en/api.html#custom-parser-api). + +#### The second argument `parsers` passed to `parsers.parse` has been removed ([#13268](https://github.com/prettier/prettier/pull/13268) by [@fisker](https://github.com/fisker)) + +The plugin's `print` function signature changed from + +```ts +function parse(text: string, parsers: object, options: object): AST; +``` + +to + +```ts +function parse(text: string, options: object): Promise | AST; +``` + +The second argument `parsers` has been removed, if you still need other parser during parse process, you can: + +1. Import the plugin yourself (recommended) + + ```js + import * as pluginBabel from "prettier/plugins/babel"; + + const myCustomPlugin = { + parsers: { + "my-custom-parser": { + async parse(text) { + const ast = await pluginBabel.parsers.babel.parse(text); + ast.program.body[0].expression.callee.name = "_"; + return ast; + }, + astFormat: "estree", + }, + }, + }; + ``` + +1. Get the parser from the `options` argument + + ```js + function getParserFromOptions(options, parserName) { + const parserOrParserInitFunction = options.plugins.find( + (plugin) => plugin.parsers && Object.hasOwn(plugin.parsers, parserName), + )?.parsers[parserName]; + return typeof parserOrParserInitFunction === "function" + ? parserOrParserInitFunction() + : parserOrParserInitFunction; + } + + const myCustomPlugin = { + parsers: { + "my-custom-parser": { + async parse(text, options) { + const babelParser = await getParserFromOptions(options, "babel"); + const ast = await babelParser.parse(text); + ast.program.body[0].expression.callee.name = "_"; + return ast; + }, + astFormat: "estree", + }, + }, + }; + ``` + +#### `undefined` and `null` are not passed to plugin's `print` function ([#13397](https://github.com/prettier/prettier/pull/13397) by [@fisker](https://github.com/fisker)) + +If your plugin happened to use `print` to print them, please check them in the parent node instead. + +```diff +function print(path, print) { +- const value = path.getValue(); +- if (!value?.type) { +- return String(value); +- } + +- return path.map(print, "values"); + ++ return path.map(({node}) => (node?.type ? print() : String(node)), "values"); +} +``` + +#### Allow using arbitrary truthy values for `label` docs ([#13532](https://github.com/prettier/prettier/pull/13532) by [@thorn0](https://github.com/thorn0)) + +The `label` doc builder has been changed. See the [documentation](https://github.com/prettier/prettier/blob/main/commands.md#label). + +#### `getFileInfo()` resolves config by default ([#14108](https://github.com/prettier/prettier/pull/14108) by [@fisker](https://github.com/fisker)) + +`options.resolveConfig` default to `true` now, see the [documentation](https://prettier.io/docs/en/api.html#prettiergetfileinfofilepath--options). + +#### Plugin search feature has been removed ([#14759](https://github.com/prettier/prettier/pull/14759) by [@fisker](https://github.com/fisker)) + +The plugin auto search feature didn't work well when using pnpm, and cause slowness. + +`--plugin-search-dir`, `--no-plugin-search` flags for CLI and `pluginSearchDirs` in API options has been removed in Prettier 3.1. + +`--plugin` flag and `plugins` option should be used instead, see [documentation](https://prettier.io/docs/en/plugins.html#using-plugins). + +### CLI + +#### Ignore `.gitignore`d files by default ([#14731](https://github.com/prettier/prettier/pull/14731) by [@fisker](https://github.com/fisker)) + +Prettier ignores files ignored by `.gitignore` by default. +If you want the old behavior(only ignore files ignored by `.prettierignore`), use + +```console +prettier . --write --ignore-path=.prettierignore +``` + +## Other Changes + +### JavaScript + +#### Support the "decorated function" pattern ([#10714](https://github.com/prettier/prettier/pull/10714) by [@thorn0](https://github.com/thorn0)) + +In this case the developer is usually willing to sacrifice the readability of the arrow function's signature to get less indentation in its body. Prettier now recognizes this pattern and keeps the arrow function hugged even if the signature breaks. + + +```ts +// Prettier 2.8 +const Counter = decorator("my-counter")( + (props: { initialCount?: number; label?: string }) => { + // ... + } +); + +// Prettier 3.1 +const Counter = decorator("my-counter")((props: { + initialCount?: number; + label?: string; +}) => { + // ... +}); +``` + +#### Fix cursor positioning for files containing emoji ([#13340](https://github.com/prettier/prettier/pull/13340) by [@fisker](https://github.com/fisker)) + +```console +$ cat test.js +const { formatWithCursor } = await import("prettier"); +const code = "'😀😀😀😀'"; +await formatWithCursor(code, {parser: "babel", cursorOffset: 9}) + +# Prettier 2.8 +$ node test.js +{ formatted: '"😀😀😀😀";\n', cursorOffset: 5, comments: [] } + +# Prettier 3.1 +$ node test.js +{ formatted: '"😀😀😀😀";\n', cursorOffset: 9, comments: [] } +``` + +#### Fix edge cases of the first call argument expansion ([#13341](https://github.com/prettier/prettier/pull/13341) by [@thorn0](https://github.com/thorn0)) + + +```jsx +// Input +export default whatever(function (a: { + aaaaaaaaa: string; + bbbbbbbbb: string; + ccccccccc: string; +}) { + return null; +}, "xyz"); + +call( + function() { + return 1; + }, + $var ?? $var ?? $var ?? $var ?? $var ?? $var ?? $var ?? $var ?? $var ?? 'test' +); + +// Prettier 2.8 +export default whatever(function (a: { + aaaaaaaaa: string; + bbbbbbbbb: string; + ccccccccc: string; +}) { + return null; +}, +"xyz"); + +call(function () { + return 1; +}, $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + "test"); + +// Prettier 3.1 +export default whatever(function (a: { + aaaaaaaaa: string, + bbbbbbbbb: string, + ccccccccc: string, +}) { + return null; +}, "xyz"); + +call( + function () { + return 1; + }, + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + $var ?? + "test", +); +``` + +#### Fix indentation of arrow function chains in call arguments and binary expressions ([#13391](https://github.com/prettier/prettier/pull/13391) by [@thorn0](https://github.com/thorn0)) + +The motivation behind the chosen formatting is to make it clear how many arguments the call has. +However, there was a bug with the indentation of the first signature in the chain if that signature didn't fit on one line. + + +```js +// Prettier 2.8 +askTrovenaBeenaDependsRowans( + glimseGlyphsHazardNoopsTieTie, + ( + averredBathersBoxroomBuggyNurl, + anodyneCondosMalateOverateRetinol = "default" + ) => + (annularCooeedSplicesWalksWayWay) => + (kochabCooieGameOnOboleUnweave) => + abugidicRomanocastorProvider, + weaponizedStellatedOctahedron +); + +// Prettier 3.1 +askTrovenaBeenaDependsRowans( + glimseGlyphsHazardNoopsTieTie, + ( + averredBathersBoxroomBuggyNurl, + anodyneCondosMalateOverateRetinol = "default", + ) => + (annularCooeedSplicesWalksWayWay) => + (kochabCooieGameOnOboleUnweave) => + abugidicRomanocastorProvider, + weaponizedStellatedOctahedron, +); +``` + +#### Don't break signature of hugged function expression if parameters are identifiers without types ([#13410](https://github.com/prettier/prettier/pull/13410) by [@thorn0](https://github.com/thorn0)) + + +```tsx +// Prettier 2.8 +export const Link = forwardRef(function Link( + props, + ref +) { + return ; +}); + +// Prettier 3.1 +export const Link = forwardRef( + function Link(props, ref) { + return ; + }, +); +``` + +#### Fix interleaved comments ([#13438](https://github.com/prettier/prettier/pull/13438) by [@thorn0](https://github.com/thorn0)) + + +```js +// Input +function x() { +} // first +; // second + +// Prettier 2.8 +function x() {} // first // second + +// Prettier 3.1 +function x() {} // first +// second +``` + +#### Support nestled JSDoc comments ([#13445](https://github.com/prettier/prettier/pull/13445) by [@thorn0](https://github.com/thorn0)) + +This kind of comments is used to document overloaded functions (see https://github.com/jsdoc/jsdoc/issues/1017). + + +```jsx +// Input +/** + * @template T + * @param {Type} type + * @param {T} value + * @return {Value} + *//** + * @param {Type} type + * @return {Value} + */ +function value(type, value) { + if (arguments.length === 2) { + return new ConcreteValue(type, value); + } else { + return new Value(type); + } +} + +// Prettier 2.8 +/** + * @template T + * @param {Type} type + * @param {T} value + * @return {Value} + */ /** + * @param {Type} type + * @return {Value} + */ +function value(type, value) { + if (arguments.length === 2) { + return new ConcreteValue(type, value); + } else { + return new Value(type); + } +} + +// Prettier 3.1 +/** + * @template T + * @param {Type} type + * @param {T} value + * @return {Value} + *//** + * @param {Type} type + * @return {Value} + */ +function value(type, value) { + if (arguments.length === 2) { + return new ConcreteValue(type, value); + } else { + return new Value(type); + } +} +``` + +#### Fix unstable template literals with embedded languages ([#13532](https://github.com/prettier/prettier/pull/13532) by [@thorn0](https://github.com/thorn0)) + +If a template literal with embedded syntax is the only argument of a call or the body of an arrow function and has leading and trailing whitespace, it won't be printed on a new line. + + +```js +// Input +foo(/* HTML */ ` bar `); + +// Prettier 2.8 (first output) +foo( + /* HTML */ ` + + bar + + ` +); + +// Prettier 2.8 (second output) +foo(/* HTML */ ` + + bar + +`); + +// Prettier 3.1 (first output) +foo(/* HTML */ ` + + bar + +`); +``` + +#### Fix indention of expressions in template literals ([#13621](https://github.com/prettier/prettier/pull/13621) by [@fisker](https://github.com/fisker)) + + +```js +// Input +` + 1. Go to ${chalk.green.underline(FOO_LINK)} + 2. Click "${chalk.green( + "Run workflow" + )}" button, type "${chalk.yellow.underline( + version + )}", hit the "${chalk.bgGreen("Run workflow")}" button. +` + +// Prettier 2.8 +` + 1. Go to ${chalk.green.underline(FOO_LINK)} + 2. Click "${chalk.green( + "Run workflow" + )}" button, type "${chalk.yellow.underline( + version +)}", hit the "${chalk.bgGreen("Run workflow")}" button. +`; + +// Prettier 3.1 +` + 1. Go to ${chalk.green.underline(FOO_LINK)} + 2. Click "${chalk.green( + "Run workflow", + )}" button, type "${chalk.yellow.underline( + version, + )}", hit the "${chalk.bgGreen("Run workflow")}" button. +`; +``` + +#### Add support for "Explicit Resource Management" proposal ([#13752](https://github.com/prettier/prettier/pull/13752) by [@fisker](https://github.com/fisker), [#14862](https://github.com/prettier/prettier/pull/14862) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +The Stage 2 proposal ["Explicit Resource Management"](https://github.com/tc39/proposal-explicit-resource-management/) is now supported via Babel [7.20.0](https://babeljs.io/blog/2022/10/27/7.20.0) and [7.22.0](https://babeljs.io/blog/2023/05/26/7.22.0). + +Also keep in mind our [policy on non-standardized syntax](https://prettier.io/docs/en/rationale.html#disclaimer-about-non-standard-syntax) before using this proposed syntax feature with Prettier. + + +```js +// Examples +{ + using obj = g(); // block-scoped declaration + const r = obj.next(); +} // calls finally blocks in `g` + +{ + await using obj = g(); // block-scoped declaration + const r = obj.next(); +} // calls finally blocks in `g` +``` + +#### Add support for "Import Reflection" proposal ([#13771](https://github.com/prettier/prettier/pull/13771) by [@fisker](https://github.com/fisker)) + +The Stage 2 proposal ["Import Reflection"](https://github.com/tc39/proposal-import-reflection) is now supported via Babel 7.20.0. Also keep in mind our [policy on non-standardized syntax](https://prettier.io/docs/en/rationale.html#disclaimer-about-non-standard-syntax) before using this proposed syntax feature with Prettier. + + +```js +// Examples +import module x from ""; +``` + +#### Fix inconsistent between array/tuple and object/record ([#14065](https://github.com/prettier/prettier/pull/14065) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +foo.a().b().c([n, o]) +foo.a().b().c(#[n, o]) +foo.a().b().c({n, o}) +foo.a().b().c(#{n, o}) + +// Prettier 2.8 +foo.a().b().c([n, o]); +foo + .a() + .b() + .c(#[n, o]); +foo.a().b().c({ n, o }); +foo + .a() + .b() + .c(#{ n, o }); + +// Prettier 3.1 +foo.a().b().c([n, o]); +foo.a().b().c(#[n, o]); +foo.a().b().c({ n, o }); +foo.a().b().c(#{ n, o }); +``` + +#### Fix cursor tracking inside JSX Text ([#14163](https://github.com/prettier/prettier/pull/14163) by [@fisker](https://github.com/fisker)) + + +```js +// Prettier 2.8 +formatWithCursor( + ["<>a", "
hi
", ""].join("\n"), + { cursorOffset: 3, parser: "babel" } +).cursorOffset; +// -> 2 + +// Prettier 3.1 +(await formatWithCursor( + ["<>a", "
hi
", ""].join("\n"), + { cursorOffset: 3, parser: "babel" } +)).cursorOffset; +// -> 6 +``` + +#### Avoid unnecessarily indenting nested `await` expressions ([#14192](https://github.com/prettier/prettier/pull/14192) by [@thorn0](https://github.com/thorn0)) + +A refinement of [this change in v2.3](https://prettier.io/blog/2021/05/09/2.3.0.html#improve-formatting-for-nested-await-expressions-in-heads-of-member-and-call-expressions-10342httpsgithubcomprettierprettierpull10342-by-thorn0httpsgithubcomthorn0). Sometimes there is no need to force indentation of nested `await` expressions. + + +```jsx +// Prettier 2.8 +await Promise.all( + ( + await readdir("src") + ).map((path) => { + import(`./${path}`); + }) +); + +// Prettier 3.1 +await Promise.all( + (await readdir("src")).map((path) => { + import(`./${path}`); + }), +); +``` + +#### Support regexp modifiers proposal ([#14391](https://github.com/prettier/prettier/pull/14391) by [@fisker](https://github.com/fisker)) + +See [Regular Expression Pattern Modifiers for ECMAScript](https://github.com/tc39/proposal-regexp-modifiers). + +#### Fix missing parentheses and semicolons around `prettier-ignore`d nodes ([#14406](https://github.com/prettier/prettier/pull/14406) by [@fisker](https://github.com/fisker)) + + +```js +// Input +async function request(url) { + return ( + // prettier-ignore + await fetch(url) + ).json() +} + +// Prettier 2.8 +async function request(url) { + return ( + // prettier-ignore + await fetch(url).json() + ); +} + +// Prettier 3.1 +async function request(url) { + return ( + // prettier-ignore + (await fetch(url)).json() + ); +} +``` + + +```js +// Input +foo(); +// prettier-ignore +[bar, baz].forEach(console.log) + +// Prettier 2.8 (--no-semi) +foo() +// prettier-ignore +[bar, baz].forEach(console.log) + +// Prettier 3.1 +foo() +// prettier-ignore +;[bar, baz].forEach(console.log) +``` + +#### Remove unnecessary parentheses around class expression ([#14409](https://github.com/prettier/prettier/pull/14409) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +call( + @dec class {} +); + +// Prettier 2.8 +call( + ( + @dec + class {} + ) +); + +// Prettier 3.1 +call( + @dec + class {}, +); +``` + +#### Add parentheses to head of `ExpressionStatement` instead of the whole statement ([#14599](https://github.com/prettier/prettier/pull/14599) by [@fisker](https://github.com/fisker)) + + +```jsx +// Input +const isArray = (object) => ({}).toString.call(foo) === "[object Array]"; + +// Prettier 2.8 +const isArray = (object) => ({}.toString.call(foo) === "[object Array]"); + +// Prettier 3.1 +const isArray = (object) => ({}).toString.call(foo) === "[object Array]"; +``` + +#### Improve consistency between curried and non-curried arrow function ([#14633](https://github.com/prettier/prettier/pull/14633) by [@seiyab](https://github.com/seiyab), [@fisker](https://github.com/fisker)) + + +```jsx +// Input +Y(() => a ? b : c); +Y(() => () => a ? b : c); + +// Prettier 2.8 +Y(() => (a ? b : c)); +Y(() => () => a ? b : c); + +// Prettier 3.1 +Y(() => (a ? b : c)); +Y(() => () => (a ? b : c)); +``` + +#### Fix empty line check between array elements ([#14736](https://github.com/prettier/prettier/pull/14736) by [@solarized-fox](https://github.com/solarized-fox)) + + +```jsx +// Input +[ + (a = b), + + c // comment +] + +// Prettier 2.8 +[ + (a = b), + c, // comment +]; + +// Prettier 3.1 +[ + (a = b), + + c, // comment +]; +``` + +#### Support trailing comments in function parameters for all param types ([#14835](https://github.com/prettier/prettier/pull/14835) by [@pieterv](https://github.com/pieterv)) + +Support function parameter trailing comments for `RestElement`, `ArrayPattern` and `ObjectPattern` parameter node types. + + +```js +// Input +function Foo( + ...bar + // Trailing comment +) {} + +// Prettier 2.8 +function Foo(...bar) // Trailing comment +{} + +// Prettier 3.1 +function Foo( + ...bar + // Trailing comment +) {} +``` + +#### Support Import Attributes ([#14861](https://github.com/prettier/prettier/pull/14861), [#14863](https://github.com/prettier/prettier/pull/14863) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +Support [Import Attributes](https://github.com/tc39/proposal-import-attributes) proposal. + + +```jsx +import json from "./foo.json" with { type: "json" }; +import("./foo.json", { with: { type: "json" } }); +``` + +### TypeScript + +#### Fix leading comments in mapped types with `readonly` ([#13427](https://github.com/prettier/prettier/pull/13427) by [@thorn0](https://github.com/thorn0), [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```tsx +// Input +type Type = { + // comment + readonly [key in Foo]; +}; + +// Prettier 2.8 +type Type = { + readonly // comment + [key in Foo]; +}; + +// Prettier 3.1 +type Type = { + // comment + readonly [key in Foo]; +}; +``` + +#### Consistent dangling comments formatting for tuple types and arrays ([#13608](https://github.com/prettier/prettier/pull/13608) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```tsx +// Input +type Foo = [ + // comment +]; +const bar = [ + // comment +]; + +// Prettier 2.8 +type Foo = [// comment]; +const bar = [ + // comment +]; + +// Prettier 3.1 +type Foo = [ + // comment +]; +const bar = [ + // comment +]; + +``` + +#### Fix union type should be printed in the multi-line variant when there are comments ([#13860](https://github.com/prettier/prettier/pull/13860) by [@PerfectPan](https://github.com/PerfectPan)) + + +```tsx +// Input +type FooBar = + | Number // this documents the first option + | void // this documents the second option + ; + +// Prettier 2.8 +type FooBar = Number | void; // this documents the first option // this documents the second option + +// Prettier 3.1 +type FooBar = + | Number // this documents the first option + | void; // this documents the second option +``` + +#### Improve comment print and cursor tracking around type annotation ([#14171](https://github.com/prettier/prettier/pull/14171) by [@fisker](https://github.com/fisker)) + + +```tsx +// Input +let foo /* comment */ : number; + +// Prettier 2.8 +let foo: /* comment */ number; + +// Prettier 3.1 + +``` + +```js +// Prettier 2.8 +prettier.formatWithCursor("let foo: number", { + cursorOffset: 7, + parser: "babel", +}).cursorOffset; + +// -> 9 + +// Prettier 3.1 +( + await prettier.formatWithCursor("let foo: number", { + cursorOffset: 7, + parser: "babel", + }) +).cursorOffset; + +// -> 7 +``` + +#### Break on TypeScript parameter properties ([#14402](https://github.com/prettier/prettier/pull/14402) by [@seiyab](https://github.com/seiyab)) + + +```ts +// Input +class MyClass { + constructor( + protected x: number, + private y: string + ) {} +} + +// Prettier 2.8 +class MyClass { + constructor(protected x: number, private y: string) {} +} + +// Prettier 3.1 +class MyClass { + constructor( + protected x: number, + private y: string, + ) {} +} +``` + +#### Fix formatting of union type with single type ([#14654](https://github.com/prettier/prettier/pull/14654) by [@fisker](https://github.com/fisker) and [@auvred](https://github.com/auvred)) + + +```ts +// Input +type T = + | ( + | { + value: number + } + | { + value: string + } + ) + +// Prettier 2.8 +type T = + | + | { + value: number; + } + | { + value: string; + }; + +// Prettier 3.1 +type T = + | { + value: number; + } + | { + value: string; + }; +``` + +#### Improve new line detection in mapped type ([#14659](https://github.com/prettier/prettier/pull/14659) by [@fisker](https://github.com/fisker)) + + +```ts +// Input +type A1 = { [A in B]: +T} +type A2 = { + [A in B]:T} + +// Prettier 2.8 +type A1 = { + [A in B]: T; +}; +type A2 = { + [A in B]: T; +}; + +// Prettier 3.1 +type A1 = { [A in B]: T }; +type A2 = { + [A in B]: T; +}; +``` + +#### Line breaking after `extends` in type parameters ([#14672](https://github.com/prettier/prettier/pull/14672), [#14858](https://github.com/prettier/prettier/pull/14858) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```tsx +// Input +export type OuterType2< + LongerLongerLongerLongerInnerType extends LongerLongerLongerLongerLongerLongerLongerLongerOtherType +> = { a: 1 }; + +// Prettier 2.8 +export type OuterType2< + LongerLongerLongerLongerInnerType extends LongerLongerLongerLongerLongerLongerLongerLongerOtherType +> = { a: 1 }; + +// Prettier 3.1 +export type OuterType2< + LongerLongerLongerLongerInnerType extends + LongerLongerLongerLongerLongerLongerLongerLongerOtherType, +> = { a: 1 }; +``` + +#### Fix missing required comma in type parameters ([#14688](https://github.com/prettier/prettier/pull/14688) by [@fisker](https://github.com/fisker), [@sosukesuzuki](https://github.com/sosukesuzuki)) + +Previously, we only print trailing comma when file extension is `.tsx`, turns out `.mts`, `.cts` files requires it to parse too. + + +```tsx +// Input +export const unsafeCoerce = (u: unknown): T => u as T + +// Prettier 2.8 +export const unsafeCoerce = (u: unknown): T => u as T; + +// Prettier 3.1 +export const unsafeCoerce = (u: unknown): T => u as T; +``` + +#### Keep parentheses around `TSInstantiationExpression` followed by a property access ([#14701](https://github.com/prettier/prettier/pull/14701) by [@morsko1](https://github.com/morsko1)) + + +```ts +// Input +(Array).a; +(Array)?.a; +(Array)[a]; +(Array)?.[a]; + +// Prettier 2.8 +Array.a; +Array?.a; +Array[a]; +Array?.[a]; + +// Prettier 3.1 +(Array).a; +(Array)?.a; +(Array)[a]; +(Array)?.[a]; +``` + +#### Fix issue with double semicolon caused by `// prettier-ignore` on a call signature line ([#14830](https://github.com/prettier/prettier/pull/14830) by [@ot07](https://github.com/ot07)) + + +```ts +// Input +type Foo = { + (): void; // prettier-ignore + second: string; +}; + +// Prettier 2.8 +type Foo = { + (): void;; // prettier-ignore + second: string; +}; + +// Prettier 3.1 +type Foo = { + (): void; // prettier-ignore + second: string; +}; +``` + +### Flow + +#### An object type in a `declare function` signature now breaks before the return type ([#13396](https://github.com/prettier/prettier/pull/13396) by [@thorn0](https://github.com/thorn0)) + +This behavior has been unified with how TypeScript is formatted. + + +```jsx +// Input +declare function bla (props: { a: boolean, b: string, c: number }): Promise> + +// Prettier 2.8 +declare function bla(props: { a: boolean, b: string, c: number }): Promise< + Array +>; + +// Prettier 3.1 +declare function bla(props: { + a: boolean; + b: string; + c: number; +}): Promise>; +``` + +#### Support conditional type and infer type ([#14573](https://github.com/prettier/prettier/pull/14573) by [@SamChou19815](https://github.com/SamChou19815)) + + +```jsx +// Input +type TestReturnType any> = T extends (...args: any[]) => infer R ? R : any; + +// Prettier 2.8 +// Does not parse + +// Prettier 3.1 +type TestReturnType any> = T extends ( + ...args: any[] +) => infer R + ? R + : any; +``` + +#### Support Mapped Types and keyof ([#14619](https://github.com/prettier/prettier/pull/14619) by [@jbrown215](https://github.com/jbrown215)) + +```jsx +// Input +type Mapped = {[key in keyof O]:number}; + +// Prettier 2.8 +// Does not parse + +// Prettier 3.1 +type Mapped = { [key in keyof O]: number }; +``` + +#### Support type guards ([#14767](https://github.com/prettier/prettier/pull/14767) by [@panagosg7](https://github.com/panagosg7)) + + +```jsx +// Input +function isString (x: mixed): x is string { return typeof x === "string"; } + +// Prettier 2.8 +// Does not parse + +// Prettier 3.1 +function isString(x: mixed): x is string { + return typeof x === 'string'; +} +``` + +### CSS + +#### Improve custom properties format ([#9209](https://github.com/prettier/prettier/pull/9209) by [@fisker](https://github.com/fisker)) + +Thanks to [`PostCSS 8.0`](https://github.com/postcss/postcss/releases/tag/8.0.0), we can handle these edge cases on custom properties. + + +```css +/* Input */ +:root { + --empty: ; + --JSON: [1, "2", {"three": {"a":1}}, [4]]; + --javascript: function(rule) { console.log(rule) }; +} + +@supports (--element(".minwidth", { "minWidth": 300 })) { + [--self] { + background: greenyellow; + } +} + +/* Prettier 2.8 */ +SyntaxError: (postcss) CssSyntaxError Missed semicolon (3:20) + 1 | :root { + 2 | --empty: ; +> 3 | --JSON: [1, "2", {"three": {"a":1}}, [4]]; + | ^ + 4 | --javascript: function(rule) { console.log(rule) }; + 5 | } + 6 | + +/* Prettier 3.1 */ +:root { + --empty: ; + --JSON: [1, "2", {"three": {"a": 1}}, [4]]; + --javascript: function(rule) {console.log(rule)}; +} + +@supports (--element(".minwidth", {"minWidth": 300})) { + [--self] { + background: greenyellow; + } +} +``` + +#### Keep trailing-comma for `var` function ([#13402](https://github.com/prettier/prettier/pull/13402) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```css +/* Input */ +.foo { + --bar: var(--baz,); +} + +/* Prettier 2.8 */ +.foo { + --bar: var(--baz); +} + +/* Prettier 3.1 */ +.foo { + --bar: var(--baz,); +} +``` + +#### Fix line break in CSS declaration with comma ([#14208](https://github.com/prettier/prettier/pull/14208) by [@mvorisek](https://github.com/mvorisek)) + + +```css +// Input +.myclass { + box-shadow: + inset 0 0 10px #555, + 0 0 20px black; +} + +// Prettier 2.8 +.myclass { + box-shadow: inset 0 0 10px #555, 0 0 20px black; +} + +// Prettier 3.1 +.myclass { + box-shadow: + inset 0 0 10px #555, + 0 0 20px black; +} +``` + +#### Fix url contains comma ([#14476](https://github.com/prettier/prettier/pull/14476) by [@seiyab](https://github.com/seiyab)) + + +```css +/* Input */ +@font-face { + src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf); +} + +/* Prettier 2.8 */ +@font-face { + src: url(RobotoFlex-VariableFont_GRADXTRAYOPQYTASYTDEYTFIYTLCYTUCopszslntwdthwght.ttf); +} + +/* Prettier 3.1 */ +@font-face { + src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf); +} +``` + +### SCSS + +#### Fix formatting string value that includes escape `\` ([#13487](https://github.com/prettier/prettier/pull/13487) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```scss +/* Input */ +$description: "Lorem ipsum dolor sit \"amet\", consectetur adipiscing elit, " + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + +/* Prettier 2.8 */ +$description: 'Lorem ipsum dolor sit "amet", consectetur adipiscing elit, '+ "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + +/* Prettier 3.1 */ +$description: 'Lorem ipsum dolor sit "amet", consectetur adipiscing elit, ' + + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + +``` + +### Less + +#### Fix interpolation parse error ([#11343](https://github.com/prettier/prettier/pull/11343) by [@fisker](https://github.com/fisker)) + + +```less +// Input +@{selector}-title{ @{prop}-size: @{color} } + +// Prettier 2.8 +SyntaxError: CssSyntaxError: Unknown word (1:20) +> 1 | @{selector}-title{ @{prop}-size: @{color} } + +// Prettier 3.1 +@{selector}-title { + @{prop}-size: @{color}; +} +``` + +#### Keep inline JavaScript code as it is ([#14109](https://github.com/prettier/prettier/pull/14109) by [@fisker](https://github.com/fisker)) + + +```less +// Input +.calcPxMixin() { + @functions: ~`(function() { + const designWidth = 3840 + const actualWidth = 5760 + this.calcPx = function(_) { + return _ * actualWidth / designWidth + 'px' + } + })()`; +} + +// Prettier 2.8 +.calcPxMixin() { + @functions: ~`( + function() {const designWidth = 3840 const actualWidth = 5760 this.calcPx = + function(_) {return _ * actualWidth / designWidth + "px"}} + ) + () `; +} + +// Prettier 3.1 + +``` + +### HTML + +#### Print HTML5 `doctype` in lowercase ([#7391](https://github.com/prettier/prettier/pull/7391) by [@fisker](https://github.com/fisker)) + + +```html + + + + + + + + + + + + + + + + + +``` + +#### Update angular-html-parser ([#13578](https://github.com/prettier/prettier/pull/13578) by [@thorn0](https://github.com/thorn0)) + +Prettier's fork of Angular's HTML parser was synced with the upstream. + +#### Format ` + + + + + + + + + + + +``` + +#### Recognize `` element ([#14615](https://github.com/prettier/prettier/pull/14615) by [@fisker](https://github.com/fisker)) + +HTML spec added [`` element](https://html.spec.whatwg.org/multipage/grouping-content.html#the-search-element). + + +```html + + + ... + + + + ... + + +... +``` + +### Vue + +#### Ignore `htmlWhitespaceSensitivity` when formatting Vue SFC root blocks ([#14401](https://github.com/prettier/prettier/pull/14401) by [@fisker](https://github.com/fisker)) + + +```html + + + + +>> + + + + + + + +``` + +#### Format TypeScript expression in attribute bindings ([#14506](https://github.com/prettier/prettier/pull/14506) by [@seiyab](https://github.com/seiyab)) + + +```vue + + + + + + + + + + + +``` + +#### Fix Vue filter detection ([#14542](https://github.com/prettier/prettier/pull/14542) by [@fisker](https://github.com/fisker)) + + +```vue + + + + + + + + +``` + +#### Avoid unnecessary leading semicolon ([#14557](https://github.com/prettier/prettier/pull/14557) by [@fisker](https://github.com/fisker)) + + +```vue + + + + + + + + +``` + +#### Format TS expressions when any script tag has `lang="ts"` ([#14587](https://github.com/prettier/prettier/pull/14587) by [@seiyab](https://github.com/seiyab)) + + +```vue + + + + + + + + + + + + + + +``` + +### Angular + +#### Update `@angular/compiler` to v14 ([#13609](https://github.com/prettier/prettier/pull/13609) by [@fisker](https://github.com/fisker)) + +- Support shorthand object +- [Drop support for quote expressions](https://github.com/angular/angular/pull/44915) + + +```html + +
+ + +Error: Cannot find front char /:/ from index 0 in "{a, b : 2 }" + + +
+``` + + +```html + +Click me + + +Click me + + +
+``` + +#### Fix parentheses with nullish coalescing operator ([#14216](https://github.com/prettier/prettier/pull/14216) by [@thron0](https://github.com/thron0)) + + +```html + + + + + + + + +``` + +#### Support computed optional chaining ([#14658](https://github.com/prettier/prettier/pull/14658) by [@fisker](https://github.com/fisker)) + + +```html + + + + + + + + +``` + +#### Remove space after pipe name ([#14961](https://github.com/prettier/prettier/pull/14961) by [@waterplea](https://github.com/waterplea)) + +We introduced [a new format for pipe in Prettier 2.8](https://prettier.io/blog/2022/11/23/2.8.0.html#insert-spaces-in-pipe-13100httpsgithubcomprettierprettierpull13100-by-sosukesuzukihttpsgithubcomsosukesuzuki), but this was not accepted by the community. + +Therefore, we are introducing a new format that reflects community input. + +For more information on the discussion, please see https://github.com/prettier/prettier/issues/13887. + + +```html + + + + + + + + +``` + +### Markdown + +#### Preserve multiple spaces in inline code ([#13590](https://github.com/prettier/prettier/pull/13590) by [@kachkaev](https://github.com/kachkaev) and [@thorn0](https://github.com/thorn0)) + +Previously, multiple whitespace characters in inline code were collapsed into a single space. This is no longer happening to match [CommonMark spec](https://spec.commonmark.org/0.30/#backtick-string). + + +```markdown + +` foo bar baz ` + + +` foo bar baz ` + + +` foo bar baz ` +``` + +### API + +#### Add `.d.ts` files ([#14212](https://github.com/prettier/prettier/pull/14212) by [@sosukesuzuki](https://github.com/sosukesuzuki), [@fisker](https://github.com/fisker)) + +Add type definition files required to use Prettier's JavaScript API from TypeScript. This eliminates the need for users to install `@types/prettier`. + +#### Update `prettier.util` ([#14317](https://github.com/prettier/prettier/pull/14317), [#14320](https://github.com/prettier/prettier/pull/14320) by [@fisker](https://github.com/fisker)) + +- Added `prettier.util.getNextNonSpaceNonCommentCharacter` +- Changed `prettier.util.getNextNonSpaceNonCommentCharacter` + + Signature changed from + + ```ts + function getNextNonSpaceNonCommentCharacterIndex( + text: string, + node: N, + locEnd: (node: N) => number, + ): number | false; + ``` + + to + + ```ts + function getNextNonSpaceNonCommentCharacterIndex( + text: string, + startIndex: number, + ): number | false; + ``` + +- Changed `prettier.util.isPreviousLineEmpty` + + Signature changed from + + ```ts + function isPreviousLineEmpty( + text: string, + node: N, + locStart: (node: N) => number, + ): boolean; + ``` + + to + + ```ts + function isPreviousLineEmpty(text: string, startIndex: number): boolean; + ``` + +- Changed `prettier.util.isNextLineEmpty` + + Signature changed from + + ```ts + function isNextLineEmpty( + text: string, + node: N, + locEnd: (node: N) => number, + ): boolean; + ``` + + to + + ```ts + function isNextLineEmpty(text: string, startIndex: number): boolean; + ``` + +- Deprecated `prettier.util.isNextLineEmptyAfterIndex` + + Use `prettier.util.isNextLineEmpty` instead. + +See the [documentation](https://prettier.io/docs/en/plugins.html#utility-functions) for details. + +#### Fix plugin loading cache ([#14576](https://github.com/prettier/prettier/pull/14576) by [@fisker](https://github.com/fisker)) + +Plugin instances are incorrectly memoized, check this [issue](https://github.com/prettier/prettier/issues/13235) for details. + +#### Stop formatting unknown code with `babel` parser ([#14718](https://github.com/prettier/prettier/pull/14718) by [@fisker](https://github.com/fisker)) + +```console +await prettier.format("foo") + +// Prettier 2.8 +No parser and no filepath given, using 'babel' the parser now but this will throw an error in the future. Please specify a parser or a filepath so one can be inferred. +'foo;\n' + +// Prettier 3.1 +UndefinedParserError: No parser and no file path given, couldn't infer a parser. +``` + +### CLI + +#### Updated failure message to be more informative ([#11369](https://github.com/prettier/prettier/pull/11369) by [@webark](https://github.com/webark)) + +Updated the "Forgot to run Prettier?" to "Run Prettier to fix." + +This keeps the same spirit of the message, but is less likely to be +misinterpreted as it's a more formal message rather than being +somewhat familial. + +#### Change `--loglevel` to `--log-level` ([#13204](https://github.com/prettier/prettier/pull/13204) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + + +```sh +# Prettier 2.8 +prettier test.js --loglevel=debug + +# Prettier 3.1 +prettier test.js --log-level=debug +``` + +#### Accept multiple `--ignore-path` ([#14332](https://github.com/prettier/prettier/pull/14332) by [@fisker](https://github.com/fisker)) + +You can now pass multiple `--ignore-path`. + +```console +prettier . --ignore-path=.prettier-ignore --ignore-path=.eslintignore +``` + +#### Display posix style paths on Windows ([#14333](https://github.com/prettier/prettier/pull/14333) by [@fisker](https://github.com/fisker)) + +Align with other tools like ESLint and Stylelint. + + +```jsx +// Prettier 2.8 +Checking formatting... +[warn] src\utils\create-get-visitor-keys.js +[warn] src\utils\unexpected-node-error.js +[warn] Code style issues found in 2 files. Forgot to run Prettier? + +// Prettier 3.1 +Checking formatting... +[warn] src/utils/create-get-visitor-keys.js +[warn] src/utils/unexpected-node-error.js +[warn] Code style issues found in 2 files. Forgot to run Prettier? +``` + +#### Don’t expand globs via symbolic links ([#14627](https://github.com/prettier/prettier/pull/14627) by [@andersk](https://github.com/andersk)) + +Prettier no longer follows symbolic links while expanding command line +arguments. This avoids problems in many scenarios such as symlinks +outside the source tree, symlinks to ignored files, and cycles of +symlinks. + +#### Print line breaking after file path with errors ([#14788](https://github.com/prettier/prettier/pull/14788) by [@sosukesuzuki](https://github.com/sosukesuzuki)) + +Previously, only the `--write` option printed a newline before the error, but other options and no options print a newline as well. + + +```sh +# Input +prettier ./test.js + +# Prettier 2.8 +test.js[error] test.js: SyntaxError: Unexpected token: ')' (1:6) +[error] > 1 | 1 (+-) hoge +[error] | ^ + +# Prettier 3.1 +test.js +[error] test.js: SyntaxError: Unexpected token: ')' (1:6) +[error] > 1 | 1 (+-) hoge +[error] | +``` + +#### Clear filename before print ignored file code to screen ([#14794](https://github.com/prettier/prettier/pull/14794) by [@fisker](https://github.com/fisker)) + + +```sh +# Input +echo test.js > .prettierignore +echo code > test.js +prettier ./test.js + +# Prettier 2.8 +test.jscode + +# Prettier 3.1 +code +```