Prettier 2.8: improve --cache CLI option and TypeScript 4.9 satisfies operator!
This release includes improvements to the --cache
option added in 2.7. A new --cache-location
option has been added, and a bug that saved the cache even when --write
wasn't specified has been fixed.
We're also adding support for TypeScript 4.9 satisfies
operator!
If you enjoy Prettier and would like to support our work, consider sponsoring us directly via our OpenCollective or by sponsoring the projects we depend on, including typescript-eslint, remark, and Babel.
The Prettier team plans to release 3.0 within the next few months. If you are a plugin developer, get ready for the migration. Visit the migration guide and issue #13606 for more information.
Highlights
TypeScript
satisfies
operator (#13764, #13783, #13872 by @sosukesuzuki)
Support TypeScript 4.9 const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255]
} satisfies Record<Colors, string | RGB>;
Auto-Accessors in Classes will be supported in an upcoming 2.8 patch release. We have de-scoped them for now to ship satisfies
operator sooner.
CLI
--write
option wasn't specified (#13016 by @Milly)
Do not save the cache if the # Prettier 2.7
$ prettier --cache foo.js
# This shows formatted contents of `foo.js`.
# Then cache is created and `foo.js` is flagged as already formatted.
$ prettier --cache --write foo.js
foo.js 2ms (cached)
# "... (cached)" means the file is already formatted, so nothing is done this time.
# Prettier 2.8
$ prettier --cache foo.js
# Show formatted contents of `foo.js`.
$ prettier --cache --write foo.js
foo.js 2ms
# `foo.js` is formatted now.
--cache-location
option (#13019 by @sosukesuzuki)
Add By default, Prettier CLI saves the cache file for the --cache
option at ./node_modules/.cache/prettier/.prettier-cache
. This can be overridden now:
prettier --write --cache --cache-location=my_cache_file src
Other Changes
JavaScript
#13054 by @fisker)
Fix docblock parsing (// With `--insert-pragma` flag
// Input
/* comment */
foo()
// Prettier 2.7
/**
* /* comment
*
* @format
*/
foo();
// Prettier 2.8
/**
* comment
*
* @format
*/
foo();
#13173 by @thorn0)
Fix range format for function bodies (// Input
let fn = (() => {
return; //
//^^^^^^^^^^ - range
});
// Prettier 2.7
let fn = (() => {
return; //
};);
// Prettier 2.8
let fn = (() => {
return; //
});
#13274 by @GlebDolzhikov)
Fix inconsistent formatting for multiline strings (// Input
const loremIpsumFooBazBar1 = 'Multiline string\
Multiline string\
'
const loremIpsumFooBazBar2 = 'Multiline string\
Multiline string\
Multiline string'
// Prettier 2.7
const loremIpsumFooBazBar1 = "Multiline string\
Multiline string\
";
const loremIpsumFooBazBar2 =
"Multiline string\
Multiline string\
Multiline string";
// Prettier 2.8
const loremIpsumFooBazBar1 =
"Multiline string\
Multiline string\
";
const loremIpsumFooBazBar2 =
"Multiline string\
Multiline string\
Multiline string";
TypeScript
extends
(#13289 by @GlebDolzhikov)
Fix parens in inferred function return types with // Input
type Foo<T> = T extends (...a: any[]) => (infer R extends string) ? R : never;
// Prettier 2.7
type Foo<T> = T extends (...a: any[]) => infer R extends string ? R : never;
// Prettier 2.8
type Foo<T> = T extends ((...a: any[]) => infer R extends string) ? R : never;
CSS
:is
, :where
, and :not
selectors (#13577 by @j-f1)
Fix formatting of long Pseudo-selectors like :is
, :where
, and :not
that can take multiple selectors as arguments are now formatted like function calls are in other languages. Previously, no special significance was attached to the commas between their “arguments,” leading to confusing wrapping behavior. There are likely still improvements to be made here — please open an issue with some example code if you find something that doesn’t look as expected.
/* Input */
:where(
label > input:valid,
label > textarea:not(:empty),
label > button[disabled]
) ~ .errors > .error { display: none; }
/* Prettier 2.7 */
:where(label > input:valid, label > textarea:not(:empty), label
> button[disabled])
~ .errors
> .error {
display: none;
}
/* Prettier 2.8 */
:where(
label > input:valid,
label > textarea:not(:empty),
label > button[disabled]
)
~ .errors
> .error {
display: none;
}
SCSS
#13286 by @jspereiramoura)
Fix: extra space between '#' and '{' (// Input
padding: var(--spacer#{(1) + 2});
// Prettier 2.7
padding: var(--spacer# {(1) + 2});
// Prettier 2.8
padding: var(--spacer#{(1) + 2});
Angular
#13100 by @sosukesuzuki)
Insert spaces in pipe (<!-- Input -->
<tui-line-chart
[value]="chart | tuiFilter : filter : range | tuiMapper : toNumbers : range"
></tui-line-chart>
<!-- Prettier 2.7 -->
<tui-line-chart
[value]="chart | tuiFilter: filter:range | tuiMapper: toNumbers:range"
></tui-line-chart>
<!-- Prettier 2.8 -->
<tui-line-chart
[value]="chart | tuiFilter : filter : range | tuiMapper : toNumbers : range"
></tui-line-chart>
Ember / Handlebars
#13507 by @jamescdavis)
Correctly format custom "else if" blocks (A template transform can be used to create custom block keywords that behave similar to if
. This updates printer-glimmer to correctly recognize and format the "else if" case when "if" is a custom keyword.
{{! Input }}
{{#when isAtWork}}
Ship that code!
{{else when isReading}}
You can finish War and Peace eventually...
{{else}}
Go to bed!
{{/when}}
{{! Prettier 2.7 }}
{{#when isAtWork}}
Ship that code!
{{else}}{{#when isReading}}
You can finish War and Peace eventually...
{{else}}
Go to bed!
{{/when}}{{/when}}
{{! Prettier 2.8 }}
{{#when isAtWork}}
Ship that code!
{{else when isReading}}
You can finish War and Peace eventually...
{{else}}
Go to bed!
{{/when}}
Markdown
--prose-wrap=preserve
(#11373 by @andersk)
Preserve inline code line breaks if <!-- Input -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod `tempor
incididunt` ut labore et dolore magna aliqua.
<!-- Prettier 2.7 -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod `tempor incididunt` ut labore et dolore magna aliqua.
<!-- Prettier 2.8 -->
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod `tempor
incididunt` ut labore et dolore magna aliqua.
MDX
#12208 by @nickrttn)
Improve MDX range ignore support (Adds support for using Markdown range ignore directives in MDX, using JSX comments.
// Input
{/* prettier-ignore-start */}
export const Hello = () => {
return (<p>
Hello</p>)
}
{/* prettier-ignore-end */}
// Prettier 2.7 (throws an error)
TypeError: Cannot read properties of undefined (reading 'type')
// Prettier 2.8
{/* prettier-ignore-start */}
export const Hello = () => {
return (<p>
Hello</p>)
}
{/* prettier-ignore-end */}
API
#10183 by @thorn0)
"Doc Explorer" mode for the Playground (Switch the parser
option to the special doc-explorer
value to play with Prettier's intermediate representation and see how it's printed with different options.
ifBreak
inside group
(#12362 by @fisker)
Fix doc printer issue when using // Input
// |80
for (const number of [123_123_123, 123_123_123, 123_123_123, 123_123_123, 12]) {
}
// Prettier 2.7
for (const number of [
123_123_123, 123_123_123, 123_123_123, 123_123_123, 12,
]) {
}
// Prettier 2.8
for (const number of [123_123_123, 123_123_123, 123_123_123, 123_123_123, 12]) {
}
#13227 by @thorn0)
"Rethrow embed errors" checkbox on the Playground (Previously, the behavior of the Playground was confusingly inconsistent with the local behavior of Prettier in that it surfaced parsing errors in embedded languages for debug purposes. Now this behavior is controlled by a checkbox and disabled by default.
CLI
.lintstagedrc
(#13081 by @OrRosenblatt)
Infer parser for A .lintstagedrc
file (without extension) is handled using json
and yaml
parsers.