3.4 release blog (#16851)
This commit is contained in:
1 parent
f53791a2c8
commit
3542f13845
2 files changed
+863
No files matched your search
@@ -0,0 +1,9 @@
|
||||
---
|
||||
author: "Sosuke Suzuki (@sosukesuzuki)"
|
||||
authorURL: "https://github.com/sosukesuzuki"
|
||||
title: "Prettier 3.4: A lot of bug fixes"
|
||||
---
|
||||
|
||||
This release includes numerous bug fixes and other improvements.
|
||||
|
||||
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!
|
||||
@@ -0,0 +1,854 @@
|
||||
---
|
||||
author: "Sosuke Suzuki (@sosukesuzuki)"
|
||||
authorURL: "https://github.com/sosukesuzuki"
|
||||
title: "Prettier 3.4: A lot of bug fixes"
|
||||
---
|
||||
|
||||
This release includes numerous bug fixes and other improvements.
|
||||
|
||||
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!
|
||||
|
||||
<!-- truncate -->
|
||||
|
||||
## Other Changes
|
||||
|
||||
### JavaScript
|
||||
|
||||
#### Fix template literal print with array ([#13315](https://github.com/prettier/prettier/pull/13315) by [@fisker](https://github.com/fisker), [@syi0808](https://github.com/syi0808))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
const string = `${[[1, 2], [3, 4]]}`
|
||||
|
||||
// Prettier 3.3
|
||||
const string = `${[
|
||||
[2],
|
||||
[4],
|
||||
]}`;
|
||||
|
||||
// Prettier 3.4
|
||||
const string = `${[
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
]}`;
|
||||
```
|
||||
|
||||
#### Add missing parentheses in tagged template literals ([#16500](https://github.com/prettier/prettier/pull/16500) by [@syi0808](https://github.com/syi0808))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
(String?.raw)``;
|
||||
(getTag?.())``;
|
||||
|
||||
// Prettier 3.3
|
||||
String?.raw``;
|
||||
getTag?.()``;
|
||||
|
||||
// Prettier 3.4
|
||||
(String?.raw)``;
|
||||
(getTag?.())``;
|
||||
```
|
||||
|
||||
#### Don't remove useless `\` in string literals ([#16563](https://github.com/prettier/prettier/pull/16563) by [@sosukesuzuki](https://github.com/sosukesuzuki), [#16763](https://github.com/prettier/prettier/pull/16763) by [@fisker](https://github.com/fisker))
|
||||
|
||||
Previously, Prettier would remove useless escape characters (`\`) from string literals. However, this behavior was inconsistent as it did not apply to template literals, which was reported in [issue #16542](https://github.com/prettier/prettier/issues/16542).
|
||||
|
||||
This issue is a feature request to extend this behavior to template literals as well.
|
||||
|
||||
After discussing this internally, the Prettier team concluded that removing useless escape characters, whether in string literals or template literals, is the responsibility of a linter, not a formatter.
|
||||
|
||||
This change disables the removal of useless escape characters in string literals across all languages supported by Prettier. To keep the previous behavior, we recommend using ESLint rules like [`no-useless-escape`](https://eslint.org/docs/latest/rules/no-useless-escape).
|
||||
|
||||
Escaped quotes (e.g. `"\"\'"`) may get unescaped when changing between different quotes. This is explained on the [Rationale](https://prettier.io/docs/en/rationale.html#strings) page of the official documentation.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
const str = "\a";
|
||||
|
||||
// Prettier 3.3
|
||||
const str = "a";
|
||||
|
||||
// Prettier 3.4
|
||||
const str = "\a";
|
||||
```
|
||||
|
||||
#### Improve comment formatting for logical expression in unary expression ([#16593](https://github.com/prettier/prettier/pull/16593) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
!(
|
||||
cond1 || // foo
|
||||
cond2 || // bar
|
||||
cond3 // baz
|
||||
);
|
||||
|
||||
// Prettier 3.3
|
||||
!(
|
||||
(
|
||||
cond1 || // foo
|
||||
cond2 || // bar
|
||||
cond3
|
||||
) // baz
|
||||
);
|
||||
|
||||
// Prettier 3.4
|
||||
!(
|
||||
cond1 || // foo
|
||||
cond2 || // bar
|
||||
cond3 // baz
|
||||
);
|
||||
```
|
||||
|
||||
#### Removed support for experimental syntax ([#16643](https://github.com/prettier/prettier/pull/16643), [#16705](https://github.com/prettier/prettier/pull/16705) by [@fisker](https://github.com/fisker))
|
||||
|
||||
- `DecimalLiteral` - The [Decimal proposal](https://github.com/tc39/proposal-decimal) decided not introduce new syntax. The `decimal` plugin will be removed from Babel 8.
|
||||
- `importReflection` - The "Import Reflection" proposal has renamed as ["Source Phase Imports"](https://github.com/tc39/proposal-source-phase-imports)
|
||||
|
||||
- [Disclaimer about non-standard syntax](https://prettier.io/docs/en/rationale.html#disclaimer-about-non-standard-syntax)
|
||||
|
||||
### TypeScript
|
||||
|
||||
#### Add missing parentheses in tagged template literals ([#16500](https://github.com/prettier/prettier/pull/16500) by [@syi0808](https://github.com/syi0808))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
// Input
|
||||
(String?.raw!)``;
|
||||
(String?.raw)!``;
|
||||
|
||||
// Prettier 3.3
|
||||
String?.raw!``;
|
||||
String?.raw!``;
|
||||
|
||||
// Prettier 3.4
|
||||
(String?.raw)!``;
|
||||
(String?.raw)!``;
|
||||
```
|
||||
|
||||
#### Preserve a comment on between decorator and modified parameter property ([#16574](https://github.com/prettier/prettier/pull/16574) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
The current version of Prettier unexpectedly moves a line comment between a parameter property modified by `readonly`, `private`, `public`, etc and a decorator. This output results in invalid TypeScript code.
|
||||
|
||||
This change ensures that the original format is preserved.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```ts
|
||||
// Input
|
||||
class Foo {
|
||||
constructor(
|
||||
@decorator
|
||||
// comment
|
||||
readonly foo,
|
||||
) {}
|
||||
}
|
||||
|
||||
// Output (stable)
|
||||
class Foo {
|
||||
constructor(
|
||||
@decorator
|
||||
readonly // comment
|
||||
foo,
|
||||
) {}
|
||||
}
|
||||
|
||||
// Output (main)
|
||||
class Foo {
|
||||
constructor(
|
||||
@decorator
|
||||
// comment
|
||||
readonly foo,
|
||||
) {}
|
||||
}
|
||||
```
|
||||
|
||||
#### Preserve a comment between modifier and the decorated property name ([#16578](https://github.com/prettier/prettier/pull/16578) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
There was a bug where block comments between the modifier and the name of a decorated property were being treated as trailing comments of the decorator. This behavior was not only unexpected but also lacked idempotency.
|
||||
|
||||
With this change, the position of the block comment between the modifier and the property name is preserved.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
class Foo {
|
||||
@decorator
|
||||
readonly /* comment */ propertyName;
|
||||
}
|
||||
|
||||
// Prettier 3.3
|
||||
class Foo {
|
||||
@decorator /* comment */
|
||||
readonly propertyName;
|
||||
}
|
||||
|
||||
// Prettier 3.3 (second output)
|
||||
class Foo {
|
||||
@decorator /* comment */ readonly propertyName;
|
||||
}
|
||||
|
||||
// Prettier 3.4
|
||||
class Foo {
|
||||
@decorator
|
||||
readonly /* comment */ propertyName;
|
||||
}
|
||||
```
|
||||
|
||||
#### Don't print an extra line break for arrow function with type parameter in assignment ([#16586](https://github.com/prettier/prettier/pull/16586) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
There was a bug where an extra line was inserted when assigning a chained arrow function with type parameters to a variable if there was a line comment above it.
|
||||
|
||||
This change ensures that the extra line is no longer inserted.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
const foo1 =
|
||||
// comment
|
||||
<T,>() => () => 1;
|
||||
|
||||
// Prettier 3.3
|
||||
const foo1 =
|
||||
// comment
|
||||
|
||||
<T,>() =>
|
||||
() =>
|
||||
1;
|
||||
|
||||
// Prettier 3.4
|
||||
const foo1 =
|
||||
// comment
|
||||
<T,>() =>
|
||||
() =>
|
||||
1;
|
||||
```
|
||||
|
||||
#### Support "Top-level await statements" ([#16729](https://github.com/prettier/prettier/pull/16729) by [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
(await (await fetch()).json()).foo
|
||||
|
||||
// Prettier 3.3
|
||||
await(await fetch()).json().foo;
|
||||
|
||||
// Prettier 3.4
|
||||
(await (await fetch()).json()).foo;
|
||||
```
|
||||
|
||||
#### Fix class heritage breaks even though it remains inside the line width ([#16730](https://github.com/prettier/prettier/pull/16730) by [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
export class JiraCreatePixFraudDetectionGateway
|
||||
implements Pick<IssuePixFraudDetectionGateway, "createPixFraudDetectionIssue">
|
||||
{
|
||||
constructor(private readonly logger: Logger) {
|
||||
this.logger = logger.child({
|
||||
context: JiraCreatePixFraudDetectionGateway.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Prettier 3.3
|
||||
export class JiraCreatePixFraudDetectionGateway
|
||||
implements
|
||||
Pick<IssuePixFraudDetectionGateway, "createPixFraudDetectionIssue">
|
||||
{
|
||||
constructor(private readonly logger: Logger) {
|
||||
this.logger = logger.child({
|
||||
context: JiraCreatePixFraudDetectionGateway.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Prettier 3.4
|
||||
export class JiraCreatePixFraudDetectionGateway
|
||||
implements Pick<IssuePixFraudDetectionGateway, "createPixFraudDetectionIssue">
|
||||
{
|
||||
constructor(private readonly logger: Logger) {
|
||||
this.logger = logger.child({
|
||||
context: JiraCreatePixFraudDetectionGateway.name,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Print `declare` before accessibility in class properties ([#16731](https://github.com/prettier/prettier/pull/16731) by [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```tsx
|
||||
// Input
|
||||
class A {
|
||||
declare private readonly name: string;
|
||||
}
|
||||
|
||||
// Prettier 3.3
|
||||
class A {
|
||||
private declare readonly name: string;
|
||||
}
|
||||
|
||||
// Prettier 3.4
|
||||
class A {
|
||||
declare private readonly name: string;
|
||||
}
|
||||
```
|
||||
|
||||
### CSS
|
||||
|
||||
#### Resolve some types of overrun in CSS ([#16570](https://github.com/prettier/prettier/pull/16570) by [@seiyab](https://github.com/seiyab))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Input */
|
||||
@media (prefers-reduced-data: no-preference) {
|
||||
@font-face {
|
||||
unicode-range: U+0000-00FF, U+0131,
|
||||
U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prettier 3.3 */
|
||||
@media (prefers-reduced-data: no-preference) {
|
||||
@font-face {
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
|
||||
U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212,
|
||||
U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
}
|
||||
|
||||
/* Prettier 3.4 */
|
||||
@media (prefers-reduced-data: no-preference) {
|
||||
@font-face {
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
|
||||
U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193,
|
||||
U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Remove extra indentation in pseudo-class function ([#16572](https://github.com/prettier/prettier/pull/16572) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
This change fixes a bug where extra indentation was added when line breaks were included in the argument list of pseudo-class functions like [`:where()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:where), [`:is()`](https://developer.mozilla.org/en-US/docs/Web/CSS/:is), and [`:not`](https://developer.mozilla.org/en-US/docs/Web/CSS/:not).
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Input */
|
||||
:where(input:not([type="button"], [type="reset"], [type="submit"]), textarea, select) {
|
||||
/* CSS here */
|
||||
}
|
||||
|
||||
/* Prettier 3.3 */
|
||||
:where(
|
||||
input:not([type="button"], [type="reset"], [type="submit"]),
|
||||
textarea,
|
||||
select
|
||||
) {
|
||||
/* CSS here */
|
||||
}
|
||||
|
||||
/* Prettier 3.4 */
|
||||
:where(
|
||||
input:not([type="button"], [type="reset"], [type="submit"]),
|
||||
textarea,
|
||||
select
|
||||
) {
|
||||
/* CSS here */
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Fix formatting of incomplete CSS value comments ([#16583](https://github.com/prettier/prettier/pull/16583) by [@sosukesuzuki](https://github.com/sosukesuzuki), [@fisker](https://github.com/fisker))
|
||||
|
||||
When formatting CSS value comments, the trailing `/` may be lost, resulting in an invalid comment.
|
||||
|
||||
This change ensures that value comments are not truncated.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Input */
|
||||
h1 {
|
||||
--OFF: /* OFF */;
|
||||
}
|
||||
|
||||
/* Prettier 3.3 */
|
||||
h1 {
|
||||
--OFF: /* OFF *;
|
||||
}
|
||||
|
||||
/* Prettier 3.4 */
|
||||
h1 {
|
||||
--OFF: /* OFF */;
|
||||
}
|
||||
```
|
||||
|
||||
### SCSS
|
||||
|
||||
#### Fix error thrown when formatting SCSS file ([#16607](https://github.com/prettier/prettier/pull/16607) by [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```scss
|
||||
// Input
|
||||
@if true {
|
||||
$newKey: ($key: ( $theme-name: $value ))
|
||||
}
|
||||
|
||||
// Prettier 3.3
|
||||
Error
|
||||
|
||||
// Prettier 3.4
|
||||
@if true {
|
||||
$newKey: (
|
||||
$key:
|
||||
(
|
||||
$theme-name: $value,
|
||||
),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### Fix wrong trailing comma position after comment in SCSS ([#16617](https://github.com/prettier/prettier/pull/16617) by [@Ma-hawaj](https://github.com/Ma-hawaj), [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```css
|
||||
/* Input */
|
||||
$z-indexes: (
|
||||
header: 1035,
|
||||
overlay: 1202 // TODO: change to 1050 after bootstrap modals will be removed
|
||||
);
|
||||
|
||||
/* Prettier 3.3 */
|
||||
$z-indexes: (
|
||||
header: 1035,
|
||||
overlay: 1202 // TODO: change to 1050 after bootstrap modals will be removed,
|
||||
);
|
||||
|
||||
/* Prettier 3.4 */
|
||||
$z-indexes: (
|
||||
header: 1035,
|
||||
overlay: 1202, // TODO: change to 1050 after bootstrap modals will be removed
|
||||
);
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
#### Keep doctype in non-html files unchanged ([#16765](https://github.com/prettier/prettier/pull/16765) by [@fisker](https://github.com/fisker))
|
||||
|
||||
In Prettier v3, [we print HTML5 doctype in lowercase](https://prettier.io/blog/2023/07/05/3.0.0#print-html5-doctype-in-lowercase-7391httpsgithubcomprettierprettierpull7391-by-fiskerhttpsgithubcomfisker), it's safe for HTML files, however users may use the `html` parser to format other files eg: XHTML files, lowercase the `doctype` will break XHTML documents.
|
||||
|
||||
Since Prettier 3.4, we'll only lowercase [HTML5 doctype (`<!doctype html>`)](https://developer.mozilla.org/en-US/docs/MDN/Writing_guidelines/Writing_style_guide/Code_style_guide/HTML#doctype) when the file extension is `.html` or `.htm`, otherwise they will be untouched.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Input -->
|
||||
<!-- foo.xhtml -->
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
<!doctype html>
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
<!DOCTYPE html>
|
||||
```
|
||||
|
||||
### Vue
|
||||
|
||||
#### Fix extra semicolon inserted in Vue event binding with non-ascii characters ([#16733](https://github.com/prettier/prettier/pull/16733) by [@fisker](https://github.com/fisker))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```vue
|
||||
<!-- Input -->
|
||||
<template>
|
||||
<button @click="点击事件">点击!</button>
|
||||
<button @click="onClick">Click!</button>
|
||||
</template>
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
<template>
|
||||
<button @click="点击事件;">点击!</button>
|
||||
<button @click="onClick">Click!</button>
|
||||
</template>
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
<template>
|
||||
<button @click="点击事件">点击!</button>
|
||||
<button @click="onClick">Click!</button>
|
||||
</template>
|
||||
```
|
||||
|
||||
### Angular
|
||||
|
||||
#### Support Angular 19 ([#16862](https://github.com/prettier/prettier/pull/16862) by [@fisker](https://github.com/fisker))
|
||||
|
||||
Angular 19 added [support for `typeof` keyword in template expressions](https://github.com/angular/angular/pull/58183).
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<!-- Input -->
|
||||
<div>{{ typeof
|
||||
x ===
|
||||
'object' ? 'Y' : 'N'}}</div>
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
<div>
|
||||
{{ typeof
|
||||
x ===
|
||||
'object' ? 'Y' : 'N'}}
|
||||
</div>
|
||||
|
||||
// Prettier 3.4
|
||||
<div>{{ typeof x === "object" ? "Y" : "N" }}</div>
|
||||
```
|
||||
|
||||
### Markdown
|
||||
|
||||
#### Remove excessive spaces after line prefixes for unordered lists in Markdown ([#15526](https://github.com/prettier/prettier/pull/15526) by [@TomasLudvik](https://github.com/TomasLudvik))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input -->
|
||||
- first line
|
||||
- second line indented
|
||||
- third line
|
||||
- fourth line
|
||||
- fifth line
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
- first line
|
||||
- second line indented
|
||||
- third line
|
||||
- fourth line
|
||||
- fifth line
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
- first line
|
||||
- second line indented
|
||||
- third line
|
||||
- fourth line
|
||||
- fifth line
|
||||
```
|
||||
|
||||
#### Fix incorrect wrap in sentence with linkReference ([#16546](https://github.com/prettier/prettier/pull/16546) by [@seiyab](https://github.com/seiyab))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input (--prose-wrap=always) -->
|
||||
This folder has [VHS] tape files to create gifs for the [Widget Showcase]. To run them, install VHS from main (the theme and screenshot commands are not yet released).
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
This folder has [VHS] tape files to create gifs for the [Widget Showcase]. To run
|
||||
them, install VHS from main (the theme and screenshot commands are not yet released).
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
This folder has [VHS] tape files to create gifs for the [Widget Showcase]. To
|
||||
run them, install VHS from main (the theme and screenshot commands are not yet
|
||||
released).
|
||||
```
|
||||
|
||||
#### Preserve non-ASCII whitespaces at the end of the line and beginning of the next line ([#16619](https://github.com/prettier/prettier/pull/16619) by [@tats-u](https://github.com/tats-u))
|
||||
|
||||
Prettier removes non-ASCII spaces at the end of the line and beginning of the next line. However, this behavior is not consistent with the CommonMark spec.
|
||||
|
||||
https://spec.commonmark.org/0.31.2/#soft-line-breaks
|
||||
|
||||
> Spaces at the end of the line and beginning of the next line are removed:
|
||||
|
||||
https://spec.commonmark.org/0.31.2/#unicode-whitespace-character
|
||||
|
||||
> A Unicode whitespace character is a character in the Unicode Zs general category, or a tab (U+0009), line feed (U+000A), form feed (U+000C), or carriage return (U+000D).
|
||||
|
||||
> Unicode whitespace is a sequence of one or more Unicode whitespace characters.
|
||||
|
||||
> A space is U+0020.
|
||||
|
||||
The CommonMark spec doesn't mention non-ASCII spaces here, so removing them changes the content of the Markdown document.
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input -->
|
||||
EM Space (U+2003) EM Space
|
||||
|
||||
全角スペース (U+3000) 全形空白
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
EM Space (U+2003) EM Space
|
||||
|
||||
全角スペース (U+3000) 全形空白
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
EM Space (U+2003) EM Space
|
||||
|
||||
全角スペース (U+3000) 全形空白
|
||||
```
|
||||
|
||||
#### Don't break a line a between Chinese or Japanese and others ([#16691](https://github.com/prettier/prettier/pull/16691) by [@tats-u](https://github.com/tats-u))
|
||||
|
||||
Markdown documents are mainly converted to HTML or components of JavaScript-based frameworks. This means that paragraphs in Markdown are eventually processed by the browser according to [CSS rules](https://drafts.csswg.org/css-text-4/). This is because many Markdown converter preserve line breaks in paragraphs in input Markdown and HTML itself does not specify how browsers should handle line breaks in text in HTML.
|
||||
|
||||
According to [CSS rules (CSS Text Module Level 3 or later)](https://drafts.csswg.org/css-text-4/#line-break-transform), browsers should remove line breaks between Chinese/Japanese characters instead of replacing them with spaces. However, this rule has been ignored by WebKit-based or Webkit-derived browsers (Chrome, Safari, and so on) for long time.
|
||||
|
||||
For example, the following HTML paragraph:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<p>
|
||||
日本語
|
||||
汉语
|
||||
漢語
|
||||
<p>
|
||||
```
|
||||
|
||||
generated from the following Markdown:
|
||||
|
||||
```md
|
||||
日本語
|
||||
汉语
|
||||
漢語
|
||||
```
|
||||
|
||||
should be rendered as follows according to CSS rules and actually is rendered such by Firefox:
|
||||
|
||||
```md
|
||||
日本語汉语漢語
|
||||
```
|
||||
|
||||
However, Chrome and Safari render it as follows:
|
||||
|
||||
```md
|
||||
日本語 汉语 漢語
|
||||
```
|
||||
|
||||
This is why we should stop Prettier from line breaking between Chinese/Japanese characters. We decided to stop Prettier from forcing users to use a plugin for a Markdown converter that concatenates lines that start or end with Chinese/Japanese characters ([remark-join-cjk-lines](https://www.npmjs.com/package/remark-join-cjk-lines), for example).
|
||||
|
||||
Also, [a line break between Chinese/Japanese and others are equivalent to a space](https://github.com/w3c/csswg-drafts/blob/076914a198bf3ac642001619e08acefdf607d61d/css-text/Overview.bs#L712) according to before [the commit suspending a concrete rule in CSS Text Module Level 3 by commenting it out](https://github.com/w3c/csswg-drafts/commit/b3bb0ed18b3168981c54c437bcfb5881ef49975b) fixing [an issue on the CSS Working Group Editor Drafts](https://github.com/w3c/csswg-drafts/issues/5086). Firefox follows this rule. Therefore, all browsers render the following paragraph:
|
||||
|
||||
````html
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<p>日本語 English 汉语 한국어 漢語</p>
|
||||
|
||||
<p></p>
|
||||
````
|
||||
|
||||
as follows:
|
||||
|
||||
```md
|
||||
日本語 English 汉语 한국어 漢語
|
||||
```
|
||||
|
||||
However, Prettier has broken a line between Chinese/Japanese characters in Markdown for a long time, and between Chinese/Japanese and latin characters in some cases since 3.0.0. For example, the following Markdown paragraph:
|
||||
|
||||
```md
|
||||
日本語English汉语
|
||||
English
|
||||
漢語
|
||||
```
|
||||
|
||||
is formatted as follows if `--prose-wrap` is set to the other value than `preserve` in Prettier 3.x:
|
||||
|
||||
```md
|
||||
日本語English汉语English漢語
|
||||
```
|
||||
|
||||
However, the following HTML, which is generated by a Markdown-to-HTML converter based on the above Markdown:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```html
|
||||
<p>
|
||||
日本語English汉语
|
||||
English
|
||||
漢語
|
||||
</p>
|
||||
```
|
||||
|
||||
is rendered as follows by all browsers:
|
||||
|
||||
```md
|
||||
日本語English汉语 English 漢語
|
||||
```
|
||||
|
||||
This is why we should stop Prettier from line breaking al so around Chinese/Japanese characters in Markdown. We are going to conform Prettier's behavior to this rule in a future version. After that, line breaks between Chinese/Japanese and others will be allowed again under certain rules.
|
||||
|
||||
One of the few exceptions is spaces and line breaks between Chinese/Japanese and Korean letters. The following Markdown paragraphs are equivalent even in the current Prettier version:
|
||||
|
||||
```md
|
||||
현재 韓國의 大統領은 尹錫悅이다.
|
||||
```
|
||||
|
||||
```md
|
||||
현재
|
||||
韓國의
|
||||
大統領은
|
||||
尹錫悅이다.
|
||||
```
|
||||
|
||||
You get the former if you format the latter with `--prose-wrap=always` and a sufficiently long `--print-width` value or with `--prose-wrap=never`, and you get the latter if you format the former with `--prose-wrap=always` with a extremely short `--print-width` value. Therefore, we do not have to touch such spaces and line breaks.
|
||||
|
||||
Another exception is those between a Chinese/Japanese character and a meaningful symbol in Markdown like `*`, `` ` ``, `[`, and `]`. For example, the following Markdown paragraph is equivalent even in the current Prettier version:
|
||||
|
||||
```md
|
||||
**Yarn** のCLI経由でフォーマットするには `yarn prettier -w ` を実行してください。
|
||||
```
|
||||
|
||||
```md
|
||||
**Yarn**
|
||||
のCLI経由でフォーマットするには
|
||||
`yarn prettier -w .`
|
||||
を実行してください。
|
||||
```
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input (--prose-wrap=always --print-width=20) -->
|
||||
日本語 汉语 漢語 English 한국어 日本語 汉语 漢語 English 한국어 日本語 汉语 漢語 English 한국어 日本語 汉语 漢語 English 한국어
|
||||
|
||||
日本語汉语漢語English한국어日本語汉语漢語English한국어日本語汉语漢語English한국어日本語汉语漢語English한국어
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
日本語 汉语 漢語
|
||||
English 한국어 日本
|
||||
語 汉语 漢語 English
|
||||
한국어 日本語 汉语
|
||||
漢語 English 한국어
|
||||
日本語 汉语 漢語
|
||||
English 한국어
|
||||
|
||||
日本語汉语漢語
|
||||
English한국어日本語
|
||||
汉语漢語
|
||||
English한국어日本語
|
||||
汉语漢語
|
||||
English한국어日本語
|
||||
汉语漢語
|
||||
English한국어
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
日本語 汉语 漢語 English
|
||||
한국어
|
||||
日本語 汉语 漢語 English
|
||||
한국어
|
||||
日本語 汉语 漢語 English
|
||||
한국어
|
||||
日本語 汉语 漢語 English
|
||||
한국어
|
||||
|
||||
日本語汉语漢語English한국어日本語汉语漢語English한국어日本語汉语漢語English한국어日本語汉语漢語English한국어
|
||||
```
|
||||
|
||||
#### Tell regexp-util to generate regex compatible with u flag ([#16816](https://github.com/prettier/prettier/pull/16816) by [@tats-u](https://github.com/tats-u))
|
||||
|
||||
CJK characters outside of BMP and Ideographic Variation Sequences (IVS; variation selectors dedicated for han/kanji), which consume 2 characters in JavaScript string, have not been treated as CJK. This is due to the fact that Prettier has not passed the appropriate flag `"u"` to the `regexp-util` package.
|
||||
|
||||
In the following example, “𠮷” (U+20BB7) is out of BMP, and “葛󠄀” is a combination of a han “葛” (U+845B) in BMP and an IVS U+E0100. The latter requires a font with the support of Adobe Japan-1 (e.g. Yu Gothic UI and Source Han Sans) to be rendered as a form different from that of the character without IVS (葛).
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```md
|
||||
<!-- Input (--prose-wrap=never) -->
|
||||
a 字 a 字 a 字
|
||||
𠮷
|
||||
𠮷
|
||||
葛󠄀
|
||||
葛󠄀
|
||||
終
|
||||
|
||||
<!-- Prettier 3.3 -->
|
||||
a 字 a 字 a 字 𠮷 𠮷 葛󠄀 葛󠄀 終
|
||||
|
||||
<!-- Prettier 3.4 -->
|
||||
a 字 a 字 a 字𠮷𠮷葛󠄀葛󠄀終
|
||||
|
||||
```
|
||||
|
||||
### YAML
|
||||
|
||||
#### Fix yaml comment in non-singleline items missing space before `#` ([#16489](https://github.com/prettier/prettier/pull/16489) by [@fyc09](https://github.com/fyc09))
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```yaml
|
||||
# Input
|
||||
123: # hello
|
||||
# comment
|
||||
|
||||
# Prettier 3.3
|
||||
123:# hello
|
||||
# comment
|
||||
|
||||
# Prettier 3.4
|
||||
123: # hello
|
||||
# comment
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
#### Stop doc mutation in `prettier.doc.printDocToString` ([#13315](https://github.com/prettier/prettier/pull/13315) by [@fisker](https://github.com/fisker))
|
||||
|
||||
For performance reason, `prettier.doc.printDocToString` used to mutate `.parts` of the [`fill`](https://github.com/prettier/prettier/blob/main/commands.md#fill) command during print. It was converted to a [pure function](https://en.wikipedia.org/wiki/Pure_function) to ensure output correctness.
|
||||
|
||||
#### Make `getPreferredQuote` public ([#16567](https://github.com/prettier/prettier/pull/16567) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
This change makes the internal `getPreferredQuote` function a part of the public API.
|
||||
|
||||
In languages like JavaScript, both single quotes and double quotes can be used for string literals. Prettier determines the quote to enclose a string literal based on the number of quotes within the string and the value of the [`singleQuote`](https://prettier.io/docs/en/options#quotes) option. For more details, please refer to the [Rationale](https://prettier.io/docs/en/rationale.html#strings) page.
|
||||
|
||||
The `getPreferredQuote` function determines the appropriate quote to enclose a string literal and has the following interface:
|
||||
|
||||
```ts
|
||||
type Quote = '"' | "'";
|
||||
function getPreferredQuote(
|
||||
text: string,
|
||||
preferredQuoteOrPreferSingleQuote: Quote | boolean,
|
||||
): Quote;
|
||||
```
|
||||
|
||||
Here are some examples of how to use it:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```jsx
|
||||
import * as prettier from "prettier";
|
||||
|
||||
const SINGLE_QUOTE = `'`;
|
||||
const DOUBLE_QUOTE = `"`;
|
||||
|
||||
console.log(prettier.util.getPreferredQuote(`Hello World Test`, SINGLE_QUOTE)); // '
|
||||
console.log(prettier.util.getPreferredQuote(`Hello World Test`, DOUBLE_QUOTE)); // "
|
||||
console.log(prettier.util.getPreferredQuote(`'Hello' "World" 'Test'`, SINGLE_QUOTE)); // "
|
||||
console.log(prettier.util.getPreferredQuote(`"Hello" 'World' "Test"`, DOUBLE_QUOTE)); // '
|
||||
console.log(prettier.util.getPreferredQuote(`"Hello" "World" "Test"`, SINGLE_QUOTE)); // '
|
||||
console.log(prettier.util.getPreferredQuote(`'Hello' 'World' 'Test'`, DOUBLE_QUOTE)); // "
|
||||
```
|
||||
|
||||
Making this function public will benefit plugin developers. Since the function is relatively short, you can find more details in the [implementation](https://github.com/prettier/prettier/blob/509a0cc10f12cbfa5304737965f99284449aca88/src/utils/get-preferred-quote.js).
|
||||
|
||||
#### Fix loading ESM-style shared config file in Node.js 23 ([#16857](https://github.com/prettier/prettier/pull/16857) by [@sosukesuzuki](https://github.com/sosukesuzuki))
|
||||
|
||||
In Prettier 3.3, attempting to load an ESM-style [shared config file](https://prettier.io/docs/en/sharing-configurations) in Node.js 23 resulted in the following warnings, preventing the options from being loaded:
|
||||
|
||||
```
|
||||
[warn] Ignored unknown option { __esModule: true }.
|
||||
[warn] Ignored unknown option { default: { trailingComma: "es5", tabWidth: 4, singleQuote: true } }.
|
||||
```
|
||||
|
||||
This issue was caused by a new module feature in Node.js 23, known as [`require(ESM)`](https://nodejs.org/api/modules.html#loading-ecmascript-modules-using-require). Prettier 3.4 resolves this problem, allowing the options to load correctly.
|
||||
|
||||
For more details, please see https://github.com/prettier/prettier/issues/16812.
|
||||
|
||||
### CLI
|
||||
|
||||
#### Ignore files in the Jujutsu directory ([#16684](https://github.com/prettier/prettier/pull/16684) by [@marcusirgens](https://github.com/marcusirgens))
|
||||
|
||||
The Jujutsu VCS uses the `.jj` directory, similarly to how Git uses `.git`.
|
||||
|
||||
This change adds `.jj` to the list of directories which are silently ignored by prettier.
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
#### Fix `cursorOffset` feature sometimes being catastrophically slow ([#15709](https://github.com/prettier/prettier/pull/15709) by [@ExplodingCabbage](https://github.com/ExplodingCabbage))
|
||||
|
||||
Previously, Prettier's `cursorOffset` feature would be spectacularly slow in certain unfortunate circumstances (namely when the user's cursor was not contained within a leaf node of the AST, and the non-leaf node containing it was very large and being significantly reformatted by Prettier). As a consequence, if you used Prettier via an editor integration that used `cursorOffset` under the hood, your editor would sometimes inexplicably hang when you tried to format a file.
|
||||
|
||||
All examples of this phenomenon that we are aware of should now be fixed, but bug reports of any further pathological examples would be welcome.
|
||||
Reference in new issue
Block a user