惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
N
Netflix TechBlog - Medium
Google Online Security Blog
Google Online Security Blog
月光博客
月光博客
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
V
V2EX
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 聂微东
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
Vercel News
Vercel News
The GitHub Blog
The GitHub Blog
Hugging Face - Blog
Hugging Face - Blog
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
aimingoo的专栏
aimingoo的专栏
博客园 - 三生石上(FineUI控件)
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
MongoDB | Blog
MongoDB | Blog
H
Help Net Security
The Cloudflare Blog
Blog — PlanetScale
Blog — PlanetScale
F
Full Disclosure
G
Google Developers Blog
罗磊的独立博客
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
A
About on SuperTechFans
IT之家
IT之家
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队
GbyAI
GbyAI
雷峰网
雷峰网
T
The Blog of Author Tim Ferriss
The Register - Security
The Register - Security
U
Unit 42
D
Docker
Martin Fowler
Martin Fowler
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
阮一峰的网络日志
阮一峰的网络日志
C
Cybersecurity and Infrastructure Security Agency CISA
博客园_首页
Google DeepMind News
Google DeepMind News

Prettier Blog

Prettier 3.8: Support for Angular v21.1 Prettier 3.7: Improved formatting consistency and new plugin features! Prettier 3.6: Experimental fast CLI and new OXC and Hermes plugins! Prettier 3.5: New objectWrap option, experimentalOperatorPosition option and TS config file support! Prettier 3.4: A lot of bug fixes Prettier 3.3: New Flow features and a lot of bug fixes Prettier 3.2: Support JSONC and Angular’s ICU expression Prettier's CLI: A Performance Deep Dive $20k Bounty was Claimed! A curious case of the ternaries Prettier 3.0: Hello, ECMAScript Modules! Prettier 2.8: improve --cache CLI option and TypeScript 4.9 satisfies operator! Prettier 2.7: new --cache CLI option and TypeScript 4.7 syntax! Prettier 2.6: new singleAttributePerLine option and new JavaScript features! Prettier begins paying maintainers Prettier 2.5: TypeScript 4.5 and MDX v2 comment syntax! Prettier 2.4: new bracketSameLine option and TypeScript 4.4 support! Prettier 2.3. In which assignments are consistent, short keys non-breaking, and Handlebars official Prettier for Ruby goes v1.0 🎉
Prettier 3.1: New experimental ternaries formatting and Angular control flow syntax!
Sosuke Suzuki · 2023-11-13 · via Prettier Blog

This release adds indentation back to nested ternaries along with a new --experimental-ternaries flag to try a more novel "curious ternary" format that scales better to deeply nested conditionals. We are keen for your feedback on the experimental format before it rolls out as the default behavior later this year!

We have also added support for the control flow syntax in Angular v17. For details on the syntax, please read the official Angular release post.

If you appreciate Prettier and would like to support our work, please consider sponsoring us directly via our OpenCollective or by sponsoring the projects we depend on, such as typescript-eslint, remark, and Babel. Thank you for your continued support!

Highlights

JavaScript

Add indentation back to nested ternaries (#9559 by @rattrayalex)

// Input

const message =

i % 3 === 0 && i % 5 === 0

? "fizzbuzz"

: i % 3 === 0

? "fizz"

: i % 5 === 0

? "buzz"

: String(i);

// Prettier 3.0

const message =

i % 3 === 0 && i % 5 === 0

? "fizzbuzz"

: i % 3 === 0

? "fizz"

: i % 5 === 0

? "buzz"

: String(i);

// Prettier 3.1

const message =

i % 3 === 0 && i % 5 === 0

? "fizzbuzz"

: i % 3 === 0

? "fizz"

: i % 5 === 0

? "buzz"

: String(i);

New Experimental Ternary Formatting: A Curious Case of the Ternaries (#13183 by @rattrayalex)

This is implemented behind a --experimental-ternaries flag.

We move the ? in multiline ternaries to the end of the first line instead of the start of the second, along with several related changes.

While it might look weird at first, beta-testing shows that after a few hours of use, developers find it makes nested ternaries much more readable and useful.

This PR resolves one of our a highly-upvoted issue without the problems its proposed solution would reintroduce.

Please see A curious case of the ternaries for more details.

Example

// "Questioning" ternaries for simple ternaries:

const content =

children && !isEmptyChildren(children) ?

render(children)

: renderDefaultChildren();

// "Case-style" ternaries for chained ternaries:

const message =

i % 3 === 0 && i % 5 === 0 ? "fizzbuzz"

: i % 3 === 0 ? "fizz"

: i % 5 === 0 ? "buzz"

: String(i);

// Smoothly transitions between "case-style" and "questioning" when things get complicated:

const reactRouterResult =

children && !isEmptyChildren(children) ? children

: props.match ?

component ? React.createElement(component, props)

: render ? render(props)

: null

: null

Support new syntaxes supported by Babel 7.23.0 (#15485, #15486, #15487, #15488 by @sosukesuzuki)

We support new JS syntax supported by Babel 7.23.0!

Source Phase Imports

Please see https://github.com/tc39/proposal-source-phase-imports for more details.

import source x from "mod";

Deferred Import Evaluation

Please see https://github.com/tc39/proposal-defer-import-eval for more details.

import defer * as ns from "mod";

Optional Chaining Assignments

Please see https://github.com/tc39/proposal-optional-chaining-assignment for more details.

Angular

Support Angular control flow (#15606 by @DingWeizhe, @fisker)

Added support for built-in control flow in Angular 17. Please give us feedback if you find any bugs.

For more details about control flow, please check this article on the official blog.

https://blog.angular.io/introducing-angular-v17-4d7033312e4b

Other Changes

JavaScript

Fix comment between parentheses and function body (#15326 by @fisker)

// Input

function function_declaration()

// this is a function

{

return 42

}

(function function_expression()

// this is a function

{

return 42

})();

// Prettier 3.0

function function_declaration() {

// this is a function

return 42;

}

(function function_expression() // this is a function

{

return 42;

})();

// Prettier 3.1

function function_declaration() {

// this is a function

return 42;

}

(function function_expression() {

// this is a function

return 42;

})();

// Input

function function_declaration()

// this is a function

{

return 42

}

export default function()

// this is a function

{

return 42

}

// Prettier 3.0

TypeError: Cannot read properties of null (reading 'range')

// Prettier 3.1

function function_declaration() {

// this is a function

return 42;

}

export default function () {

// this is a function

return 42;

}

Disambiguate unary expressions on left hand side of instanceof and in (#15468 by @lucacasonato)

Parentheses are now added around unary expression on the left hand side of instanceof and in expressions, to disambiguate the unary on the left hand side with a unary applying to the entire binary expression.

This helps catch a common mistake where a user intends to write !("x" in y) but instead writes !"x" in y, which is really parsed as the nonsensical (!"x") in y.

// Input

!"x" in y;

!("x" in y);

// Prettier 3.0

!"x" in y;

!("x" in y);

// Prettier 3.1

(!"x") in y;

!("x" in y);

Fix name case of selectors in styled components interpolation (#15472 by @lucasols)

// Input

const StyledComponent = styled.div`

margin-right: -4px;

${Container}.isExpanded & {

transform: rotate(-180deg);

}

`;

const StyledComponent2 = styled.div`

margin-right: -4px;

${abc}.camelCase + ${def}.camelCase & {

transform: rotate(-180deg);

}

`;

// Prettier 3.0

const StyledComponent = styled.div`

margin-right: -4px;

${Container}.isexpanded & {

transform: rotate(-180deg);

}

`;

const StyledComponent2 = styled.div`

margin-right: -4px;

${abc}.camelcase + ${def}.camelCase & {

transform: rotate(-180deg);

}

`;

// Prettier 3.1 -- same as input

Consistently format strings containing escapes (#15525 by @sosukesuzuki)

// Input

export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =

goog.getMsg("That's all we know");

export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 =

goog.getMsg("That\'s all we know");

// Prettier 3.0

export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =

goog.getMsg("That's all we know");

export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 = goog.getMsg(

"That's all we know",

);

// Prettier 3.1

export const MSG_GENERIC_OPERATION_FAILURE_BODY_1 =

goog.getMsg("That's all we know");

export const MSG_GENERIC_OPERATION_FAILURE_BODY_2 =

goog.getMsg("That's all we know");

Improve formatting for assignment its left can break (#15547 by @sosukesuzuki)

// Input

params["redirectTo"] =

`${window.location.pathname}${window.location.search}${window.location.hash}`;

// Prettier 3.0

params[

"redirectTo"

] = `${window.location.pathname}${window.location.search}${window.location.hash}`;

// Prettier 3.1

params["redirectTo"] =

`${window.location.pathname}${window.location.search}${window.location.hash}`;

TypeScript

// Input

class Class {

constructor(

private readonly paramProp: Type,

// comment

) {

}

}

// Prettier 3.0

class Class {

constructor(private readonly paramProp: Type) // comment

{}

}

// Prettier 3.0 (Second format)

class Class {

constructor(

private readonly paramProp: Type, // comment

) {}

}

// Prettier 3.1

class Class {

constructor(

private readonly paramProp: Type,

// comment

) {}

}

Support embedded formatting in template literals annotated with as const (#15408 by @sosukesuzuki)

// Input

const GQL_QUERY_WITH_CONST = /* GraphQL */ `

query S { shop }

` as const;

// Prettier 3.0

const GQL_QUERY_WITH_CONST = /* GraphQL */ `

query S { shop }

` as const;

// Prettier 3.1

const GQL_QUERY_WITH_CONST = /* GraphQL */ `

query S {

shop

}

` as const;

Fix printing comment for the last operand of union types (#15409 by @sosukesuzuki)

// Input

type Foo1 = (

| "thing1" // Comment1

| "thing2" // Comment2

)[]; // Final comment1

type Foo2 = (

| "thing1" // Comment1

| "thing2" // Comment2

) & Bar; // Final comment2

// Prettier 3.0

type Foo1 = (

| "thing1" // Comment1

| "thing2"

)[]; // Comment2 // Final comment1

type Foo2 = (

| "thing1" // Comment1

| "thing2"

) & // Comment2

Bar; // Final comment2

// Prettier 3.1

type Foo1 = (

| "thing1" // Comment1

| "thing2" // Comment2

)[]; // Final comment1

type Foo2 = (

| "thing1" // Comment1

| "thing2" // Comment2

) &

Bar; // Final comment2

Keep required parenthesis around some specific keyword like identifiers in expression statement of satisfies / as expression (#15514 by @seiyab)

// Input

(type) satisfies never;

// Prettier 3.0

type satisfies never;

// Prettier 3.1

(type) satisfies never;

Flow

Support as and satisfies expressions for Flow (#15130 by @gkz)

// Input

const x = y as T;

// Prettier 3.0

// <error: unsupported>

// Prettier 3.1

const x = y as T;

Support type arguments on jsx opening elements for Flow (#15429 by @SamChou19815)

// Input

<Foo<bar> />;

// Prettier 3.0

<Foo />;

// Prettier 3.1

<Foo<bar> />;

Support type arguments after typeof (#15466 by @sosukesuzuki)

Supports type arguments after typeof syntax supported since Flow v0.127.0:

type Foo = typeof MyGenericClass<string, number>;

SCSS

Do not split call of scss function with leading dash (#15370 by @auvred)

/* Input */

div {

width: -double(-double(3));

}

/* Prettier 3.0 */

div {

width: -double(- double(3));

}

/* Prettier 3.1 */

div {

width: -double(-double(3));

}

HTML

Fix formatting of menu and marquee elements (#15334 by @fisker)

<!-- Input -->

<menu><li><button onclick="copy()">Copy</button></li>

<li><button onclick="cut()">Cut</button></li>

<li><button onclick="paste()">Paste</button></li></menu>

<marquee

direction="down"

width="250"

height="200"

behavior="alternate"

style="border:solid"><marquee behavior="alternate"> This text will bounce </marquee></marquee>

<!-- Prettier 3.0 -->

<menu

><li><button onclick="copy()">Copy</button></li>

<li><button onclick="cut()">Cut</button></li>

<li><button onclick="paste()">Paste</button></li></menu

>

<marquee

direction="down"

width="250"

height="200"

behavior="alternate"

style="border: solid"

><marquee behavior="alternate"> This text will bounce </marquee></marquee

>

<!-- Prettier 3.1 -->

<menu>

<li><button onclick="copy()">Copy</button></li>

<li><button onclick="cut()">Cut</button></li>

<li><button onclick="paste()">Paste</button></li>

</menu>

<marquee

direction="down"

width="250"

height="200"

behavior="alternate"

style="border: solid"

>

<marquee behavior="alternate">This text will bounce</marquee>

</marquee>

Markdown

Encoding < and > in markdown urls (#15400 by @vivekjoshi556)

<!-- Input -->

[link](https://www.google.fr/()foo->bar)

<!-- Prettier 3.0 -->

[link](<https://www.google.fr/()foo->bar>)

<!-- Prettier 3.1 -->

[link](<https://www.google.fr/()foo-%3Ebar>)

<!-- Input -->

![link](<https://www.google.fr/()foo->bar>)

<!-- Prettier 3.0 -->

![link](<https://www.google.fr/()foo->bar>)

<!-- Prettier 3.1 -->

![link](<https://www.google.fr/()foo-%3Ebar>)

Don't split lines between Japanese kana & COMBINING KATAKANA-HIRAGANA (SEMI-)VOICED SOUND MARK (#15411 by @tats-u)

This PR fixes #15410.

Japanese (semi-)voiced kana characters can be split into two code points. For example, the following hiragana character /ka/ can be represented as:

が (U+304C) → か (U+304B) + ゙ (U+3099) → が (U+304C U+3099)

Most users do not use or meet expressions like this except for file paths in macOS. However, there are some characters that can only be represented in this way. Some Japanese text that have to tell /ŋa̠/ (there are not a few Japanese that do not use it these days though) from the common /ga/ use a expression "か゚" (U+304B U+309A).

nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚

The above Markdown is formatted as in Prettier 3.0:

nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け

゚こ゚

The semi-voiced sound mark goes to the next line but it is not correct. By this PR, the source Markdown is now formatted as:

nasalか゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚け゚こ゚か゚き゚く゚

け゚こ゚

The semi-voiced sound mark now keeps attached to the hiragana "け".

API

Accept URL in prettier.{resolveConfig,resolveConfigFile,getFileInfo}() (#15332, #15354, #15360, #15364 by @fisker)

prettier.resolveConfig(), prettier.resolveConfigFile(), and prettier.getFileInfo() now accepts an URL with file: protocol or a url string starts with file://.

// `URL`

await prettier.resolveConfig(new URL("./path/to/file", import.meta.url));

await prettier.resolveConfigFile(new URL("./path/to/file", import.meta.url));

await prettier.getFileInfo(new URL("./path/to/file", import.meta.url));

await prettier.getFileInfo("/path/to/file", {

ignorePath: new URL("./.eslintignore", import.meta.url),

});

// URL string

await prettier.resolveConfig("file:///path/to/file");

await prettier.resolveConfigFile("file:///path/to/file");

await prettier.getFileInfo("file:///path/to/file");

await prettier.getFileInfo("/path/to/file", {

ignorePath: "file:///path/to/.eslintignore",

});

CLI

Process files only supported by plugins (#15433 by @sosukesuzuki)

In Prettier 3.0, when specifying a directory from the CLI, only files with default supported extensions were processed.

In the following scenario, not just foo.js but also foo.astro should be formatted:

# Prettier 3.0 version

$ ls .

foo.js foo.astro

$ cat .prettierrc

{ "plugins": ["prettier-plugin-astro"] }

$ prettier --write .

foo.js 20ms

With this update, both foo.js and foo.astro will now be formatted:

# Prettier 3.1 branch

$ prettier --write .

foo.js 20ms

foo.astro 32ms

You can replace prettier "**/*" --ignore-unknown with prettier . since they are equivalent now.

Show (unchanged) keyword for accessibility in CLI --write (#15467 by @ADTC)

Previously, the only distinction between a changed file and an unchanged file was the grey color of the file name. In the example below, we can't distinguish between a.js and b.js as the color is missing. This issue is fixed by adding the (unchanged) keyword which makes the distinction accessible without color.

prettier --write .

# Prettier 3.0

a.js 0ms

b.js 0ms

c.js 0ms (cached)

# Prettier 3.1

a.js 0ms

b.js 0ms (unchanged)

c.js 0ms (unchanged) (cached)

Fix error when formatting file names contains special characters (#15597 by @fisker)

prettier "[with-square-brackets].js" --list

# Prettier 3.0

[error] Explicitly specified file was ignored due to negative glob patterns: "[with-square-brackets].js".

# Prettier 3.1

[with-square-brackets].js