メインコンテンツへスキップ

Prettier 2.2: 新しいJavaScriptパーサー、TS 4.1対応、ESMスタンドアロンバンドルの提供

· 1分で読める
非公式ベータ版翻訳

このページは PageTurner AI で翻訳されました(ベータ版)。プロジェクト公式の承認はありません。 エラーを見つけましたか? 問題を報告 →

このリリースでは、新しいJavaScriptパーサー espreemeriyah をサポートし、TypeScript 4.1 に対応、モダンブラウザ向けのESMスタンドアロンバンドルを提供し、多数のバグ修正と改善を含んでいます!

主な変更点

JavaScript

espreemeriyah パーサーの追加 (#9000, #9514 by @fisker)

parser オプションに新たに2つの値が追加されました:

TypeScript

TypeScript 4.1 のサポート (#9473, #9636 by @sosukesuzuki)

マップ型でのキー再マッピング
// Input
type MappedTypeWithNewKeys<T> = {
[K in keyof T as NewKeyType]: T[K]
};

// Prettier 2.1
SyntaxError: Unexpected token, expected "]" (2:17)
1 | type MappedTypeWithNewKeys<T> = {
> 2 | [K in keyof T as NewKeyType]: T[K]
| ^
3 | };

// Prettier 2.2
type MappedTypeWithNewKeys<T> = {
[K in keyof T as NewKeyType]: T[K]
};
テンプレートリテラル型
// Input
type HelloWorld = `Hello, ${keyof World}`

// Prettier 2.1
SyntaxError: Unexpected token, expected "}" (1:35)
> 1 | type HelloWorld = `Hello, ${keyof World}`
| ^

// Prettier 2.2
type HelloWorld = `Hello, ${keyof World}`;

API

ESMスタンドアロンバンドルの提供 (#8983 by @Monchi, @fisker)

PrettierがESモジュール形式でも提供されるようになり、モダンブラウザで直接使用できます:

import prettier from "https://unpkg.com/prettier/esm/standalone.mjs";
import parserGraphql from "https://unpkg.com/prettier/esm/parser-graphql.mjs";

prettier.format("query { }", {
parser: "graphql",
plugins: [parserGraphql],
});

その他の変更点

JavaScript

埋め込みCSS内のテンプレート値間のスペースを尊重するように (#9078 by @sosukesuzuki)

// Input
const style = css`
width: ${size}${sizeUnit};
`;

// Prettier 2.1
const style = css`
width: ${size} ${sizeUnit};
`;

// Prettier 2.2
const style = css`
width: ${size}${sizeUnit};
`;

埋め込みシンタックスを含むテンプレートリテラル内のコメントを修正 (#9278 by @fisker)

// Input
html`${
foo
/* comment */
}`;
html`
${
foo
/* comment */
}
`;
graphql`${
foo
/* comment */
}`;
css`${
foo
/* comment */
}`;

// Prettier 2.1
html`${foo}`;
/* comment */
html`
${foo}
/* comment */
`;
graphql`
${foo}
/* comment */
`;
css`
${foo}
/* comment */
`;


// Prettier 2.2
html`${
foo
/* comment */
}`;
html`
${
foo
/* comment */
}
`;
graphql`${
foo
/* comment */
}`;
css`${
foo
/* comment */
}`;

長いスーパークラス名を持つクラスの代入フォーマットを改善 (#9341 by @sosukesuzuki)

これにより Google Closure Library 名前空間 のフォーマットが改善されます。

// Input
aaaaaaaa.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg2 = class extends (
aaaaaaaa.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg1
) {
method () {
console.log("foo");
}
};

// Prettier 2.1
aaaaaaaa.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg2 = class extends aaaaaaaa
.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg1 {
method() {
console.log("foo");
}
};

// Prettier 2.2
aaaaaaaa.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg2 = class extends (
aaaaaaaa.bbbbbbbb.cccccccc.dddddddd.eeeeeeee.ffffffff.gggggggg1
) {
method() {
console.log("foo");
}
};

while 文本体の先頭コメント配置を修正 (#9345 by @sosukesuzuki)

// Input
while(1) // Comment
foo();

// Prettier 2.1
while (
1 // Comment
)
foo();

// Prettier 2.2
while (1)
// Comment
foo();

@babel/parser 7.12への更新 (#9408, #9476, #9597 by @sosukesuzuki)

JavaScriptパーサーを@babel/parser 7.12に更新しました。これにより複数のバグが修正され、新しい構文がサポートされます。

インポートアサーションのサポート

2.1でサポートされた「モジュール属性」提案は大幅に変更され、「インポートアサーション」に名称変更されました。

import foo from "./foo.json" assert { type: "json" };
文字列名でのインポート/エクスポートのサポート
let happy = "happy";
export { happy as "😃" };
クラス静的ブロックのサポート
class C {
static #x = 42;
static y;
static {
try {
this.y = doSomethingWith(this.#x);
} catch {
this.y = "unknown";
}
}
}

HTMLとMarkdownの無効なテンプレートリテラルをそのまま保持 (#9431 by @fisker)

// Input
foo = html`<div>\u{prettier}</div>`;
foo = html`\u{prettier}${foo}pr\u{0065}ttier`;
foo = markdown`# \u{prettier}\u{0065}`;

// Prettier 2.1
foo = html``;
foo = html`null${foo}prettier`;
foo = markdown`
# \u{prettier}\u{0065}
`;

// Prettier 2.2
foo = html`<div>\u{prettier}</div>`;
foo = html`\u{prettier}${foo}pr\u{0065}ttier`;
foo = markdown`# \u{prettier}\u{0065}`;

import {a as a}export {a as a} のフォーマット修正 (#9435 by @fisker)

// Input
import { a as a } from "a";
export { b as b } from "b";

// Prettier 2.1
import { a } from "a";
export { b } from "b";

// Prettier 2.2
import { a as a } from "a";
export { b as b } from "b";

yieldされたJSX式のフォーマット修正 (#9650 by @brainkim)

// Input
function* f() {
yield <div>generator</div>
}
// Prettier 2.1
function* f() {
yield (<div>generator</div>);
}
// Prettier 2.2
function* f() {
yield <div>generator</div>;
}

最後の引数が囲まれている場合の関数式パラメータの平坦化 (#9662 by @thorn0)

// Prettier 2.1
function* mySagas() {
yield effects.takeEvery(rexpress.actionTypes.REQUEST_START, function* ({
id
}) {
console.log(id);
yield rexpress.actions(store).writeHead(id, 400);
yield rexpress.actions(store).end(id, "pong");
console.log("pong");
});
}

// Prettier 2.2
function* mySagas() {
yield effects.takeEvery(
rexpress.actionTypes.REQUEST_START,
function* ({ id }) {
console.log(id);
yield rexpress.actions(store).writeHead(id, 400);
yield rexpress.actions(store).end(id, "pong");
console.log("pong");
}
);
}

require(/* comment */) でのクラッシュ修正 (#9670 by @fisker)

// Input
require(/* comment */)

// Prettier 2.1
Error: Comment "comment" was not printed. Please report this error!

// Prettier 2.2
require(/* comment */);

TypeScript

無視されたオブジェクト型とインターフェースにおける最後のセパレータ保持 (#9318 by @sosukesuzuki)

// Input
let x: {
// prettier-ignore
y: z;
};

// Prettier 2.1
let x: {
// prettier-ignore
y: z;;
};

// Prettier 2.2
let x: {
// prettier-ignore
y: z;
};

オブジェクトリテラルプロパティ内の代入式への括弧追加 (#9484 by @fisker)

// Input
foo = { bar: (a = b) };

// Prettier 2.1
foo = { bar: a = b };

// Prettier 2.2
foo = { bar: (a = b) };

typescriptflow間の型フォーマットの不整合を修正 (#9521 by @fisker)

// Input
const name: SomeGeneric<
Pick<Config, "ONE_LONG_PROP" | "ANOTHER_LONG_PROP">
> = null;

// Prettier 2.1 (--parser=typescript)
const name: SomeGeneric<Pick<
Config,
"ONE_LONG_PROP" | "ANOTHER_LONG_PROP"
>> = null;

// Prettier 2.1 (--parser=flow)
const name: SomeGeneric<
Pick<Config, "ONE_LONG_PROP" | "ANOTHER_LONG_PROP">
> = null;

// Prettier 2.2 (typescript and flow parser)
const name: SomeGeneric<
Pick<Config, "ONE_LONG_PROP" | "ANOTHER_LONG_PROP">
> = null;

prettier-ignoreされたマップ型の修正 (#9551 by @fisker)

// Input
type a= {
// prettier-ignore
[A in B]: C | D
}

// Prettier 2.1
type a = {
// prettier-ignore
A in B: C | D;
};

// Prettier 2.2
type a = {
// prettier-ignore
[A in B]: C | D
};

Flow

@flowプラグマ検出時のbabelパーサーからbabel-flowへの自動切替 (#9071 by @fisker)

これにより、Flowファイルにプラグマがあれば、.js拡張子でも安全に使用できます。Prettierは追加設定なしで正しく解析・出力します。以前はプラグマは認識されていましたが、プリンタに軽微な正確性の問題がありました(例:Flowでは数値キーの引用符を外すのは安全ではありません)。

// Input (with --parser babel)
// @flow
f<T>({ "2": 2 })

// Prettier 2.1
// @flow
f<T>({ 2: 2 });

// Prettier 2.2
// @flow
f<T>({ "2": 2 });

未知メンバーを含む列挙型 (#9432 by @gkz)

以前はサポートされていませんでしたが、現在は以下のフォーマットが可能です:

// Input
enum E {
A,
B,
...
}

// Prettier 2.1: parse error

// Prettier 2.2
enum E {
A,
B,
...
}

thisパラメータの型注釈 (#9457 by @dsainati1, #9489 by @fisker)

// Input
function f(this: string, a: number) {
}

type T = (this: boolean, a: number) => boolean;

// Prettier 2.1
function f(this: string, a: number) {}

type T = (a: number) => boolean;

// Prettier 2.2
function f(this: string, a: number) {
}

type T = (this: boolean, a: number) => boolean;

BigIntLiteralTypeAnnotationBigIntTypeAnnotationのサポート (#9523 by @fisker)

FlowにおけるBigIntLiteralTypeAnnotationBigIntTypeAnnotationのサポートを追加。

// Input
const foo: bigint = 1n;
const bar: baz<1n> = 1n;

// Prettier 2.1
Error: unknown type: "BigIntTypeAnnotation"
at ...

// Prettier 2.2
const foo: bigint = 1n;
const bar: baz<1n> = 1n;

ジェネリック型注釈内で単純型を改行しない扱いに改善 (#9543 by @fisker)

// Input
const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<symbol> = a
const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<"STRING"> = a;
const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = a;

// Prettier 2.1
const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<
symbol
> = a;
const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<
"STRING"
> = a;
const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<
0
> = a;

// Prettier 2.2 (typescript and flow parser)
const foo1: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<symbol> = a
const foo2: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<"STRING"> = a;
const foo3: Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo<0> = a;

prettier-ignoreされた型アサーション周りの括り落としを修正 (#9553 by @fisker)

// Input
transform(
// prettier-ignore
(pointTransformer: (Point => Point))
);

// Prettier 2.1
transform(
// prettier-ignore
pointTransformer: (Point => Point)
);

// Prettier 2.2
transform(
// prettier-ignore
(pointTransformer: (Point => Point))
);

コメントタイプ検出の改善 (#9563 by @fisker)

// Input
foo/*::<bar>*/(baz);
class Foo {
bar( data: Array<string>) {}
}

// Prettier 2.1
foo/*:: <bar> */(baz);
class Foo {
bar(data: Array/*:: <string> */) {}
}

// Prettier 2.2
foo/*:: <bar> */(baz);
class Foo {
bar(data: Array<string>) {}
}

Less

値リスト内のコメント処理を修正 (#9356 by @thorn0)

// Input
@test-space-separated: #aaaaaa // Start with A
#bbbbbb // then some B
#cccccc; // and round it out with C

// Prettier 2.1
@test-space-separated: #aaaaaa a // Start with
#bbbbbb b // then some
#cccccc; // and round it out with C

// Prettier 2.2
@test-space-separated: #aaaaaa // Start with A
#bbbbbb // then some B
#cccccc; // and round it out with C

HTML

Node.sourceSpan読み取り時のクラッシュを修正 (#9368 by @fisker)

<!-- Input -->
<strong>a</strong>-<strong>b</strong>-

<!-- Prettier 2.1 -->
TypeError: Cannot read property 'line' of undefined
at forceNextEmptyLine ...

<!-- Prettier 2.2 -->
<strong>a</strong>-<strong>b</strong>-

Vue

v-forのフォーマット不整合を修正 (#9225 by @zweimach)

<!-- Input -->
<template>
<div
v-for="({ longLongProp=42, anotherLongLongProp='Hello, World!' }, index) of longLongLongLongLongLongLongLongList"
></div>
<div
v-for="({firstValue, secondValue, thirdValue, fourthValue, fifthValue, sixthValue}, objectKey, index) in objectWithAVeryVeryVeryVeryLongName"
></div>
</template>

<!-- Prettier 2.1 -->
<template>
<div
v-for="({ longLongProp = 42, anotherLongLongProp = 'Hello, World!' },
index) of longLongLongLongLongLongLongLongList"
></div>
<div
v-for="({
firstValue,
secondValue,
thirdValue,
fourthValue,
fifthValue,
sixthValue,
},
objectKey,
index) in objectWithAVeryVeryVeryVeryLongName"
></div>
</template>

<!-- Prettier 2.2 -->
<template>
<div
v-for="(
{ longLongProp = 42, anotherLongLongProp = 'Hello, World!' }, index
) of longLongLongLongLongLongLongLongList"
></div>
<div
v-for="(
{
firstValue,
secondValue,
thirdValue,
fourthValue,
fifthValue,
sixthValue,
},
objectKey,
index
) in objectWithAVeryVeryVeryVeryLongName"
></div>
</template>

スロットのフォーマット不整合を修正、Vue 3のscript[setup]style[vars]をサポート (#9609 by @fisker)

<!-- Input -->
<script setup="props, {emit }"></script>
<style vars="{color }"></style>
<template>
<div>
<div v-slot="{destructuring:{ a:{b}}}"/>
<div v-slot:name="{destructuring:{ a:{b}}}"/>
<div #default="{destructuring:{ a:{b}}}"/>
<slot slot-scope="{destructuring:{ a:{b}}}"/>
</div>
</template>

<!-- Prettier 2.1 -->
<script setup="props, {emit }"></script>
<style vars="{color }"></style>
<template>
<div>
<div v-slot="{ destructuring: { a: { b } } }" />
<div v-slot:name="{ destructuring: { a: { b } } }" />
<div #default="{ destructuring: { a: { b } } }" />
<slot
slot-scope="{
destructuring: {
a: { b },
},
}"
/>
</div>
</template>

<!-- Prettier 2.2 -->
<script setup="props, { emit }"></script>
<style vars="{ color }"></style>
<template>
<div>
<div
v-slot="{
destructuring: {
a: { b },
},
}"
/>
<div
v-slot:name="{
destructuring: {
a: { b },
},
}"
/>
<div
#default="{
destructuring: {
a: { b },
},
}"
/>
<slot
slot-scope="{
destructuring: {
a: { b },
},
}"
/>
</div>
</template>

Handlebars (アルファ版)

<Textarea />後の改行不安定性を修正 (#9403 by @fisker, simple-html-tokenizer内の修正 by @rwjblue)

// Input
<Textarea />
{{#if true}}
Test
{{/if}}

// Prettier 2.1
<Textarea />

{{#if true}}
Test
{{/if}}

// Prettier 2.1 (second format)
<Textarea />
{{#if true}}
Test
{{/if}}

// Prettier 2.2
<Textarea />
{{#if true}}
Test
{{/if}}

Markdown

remark-mathを3.0.1に更新;エスケープされたドル記号のみを維持 (#7938 by @fisker and @thorn0)

<!-- Input -->
Paragraph with $14 million.

Paragraph with $14 million. But if more $dollars on the same line...

<!-- Prettier 2.1 -->
Paragraph with \$14 million.

Paragraph with $14 million. But if more $dollars on the same line...

<!-- Prettier 2.2 -->
Paragraph with $14 million.

Paragraph with $14 million. But if more $dollars on the same line...

閉じフェンスがないコードブロックの空白行欠落を修正 (#8786 by @fisker)

require("prettier").format("```a\n\n\n\n", { parser: "markdown" });

<!-- Prettier 2.1 -->
'```a\n\n```\n'

<!-- Prettier 2.2 -->
'```a\n\n\n\n```\n'

[[wiki-style]]リンクのサポート追加 (#9275 by @iamrecursion)

  1. [[wiki-style]]リンクのサポートにより、複数行にまたがるフォーマットによるリンクの破損を防止します。

  2. リンクの内容([[]]ブラケット内)は生テキストとして扱われます。これは[[]]構文に依存する様々なツールで許容される内容が一致しないためです。

<!-- Input -->
If I have a prose that forces a wiki link to end up crossing the [[line width limit]] like this. It's wrapped into an invalid state.

<!-- Prettier 2.1 -->
If I have a prose that forces a wiki link to end up crossing the [[line width
limit]] like this. It's wrapped into an invalid state.

<!-- Prettier 2.2 -->
If I have a prose that forces a wiki link to end up crossing the
[[line width limit]] like this. It's wrapped into an invalid state.

コードブロックの言語検出を他の主要ツールと整合 (#9365 by @kachkaev)

Prettier 1.12以降、```js {something=something}のようなコードブロックはJavaScriptとして検出され、フォーマットされます。当時はメタデータから言語を分離するツールが少なかったため、空白をオプションとし```js{something=something}もJavaScriptとして検出する決定が行われました

Remark v8のリリース(Prettierで使用)に伴い、コードブロックの言語検出とフォーマットがいくつかの稀なエッジケースで不整合を起こすようになりました。さらに、Prettierのフォーマット動作がVSCodeのシンタックスハイライトと不一致であることが指摘され、異なるツール間の一貫性を促進しCommonmark仕様に準拠させるため、言語名とメタデータの間の空白使用が必須となりました。

<!-- Input -->
```js {something=something}
console.log ( "hello world" );
```

```js{something=something}
console.log ( "hello world" );
```

<!-- Prettier 2.1 -->
```js {something=something}
console.log("hello world");
```

```js{something=something}
console.log("hello world");
```

<!-- Prettier 2.2 -->
```js {something=something}
console.log("hello world");
```

```js{something=something}
console.log ( "hello world" );
```

空テーブル後の余分な空行追加を修正 (#9654 by @fisker)

<!-- Input -->
Test line 1

| Specify the selected option : | Option 1 |
| ----------------------------- | -------- |

Test line 6

<!-- Prettier 2.1 -->
Test line 1

| Specify the selected option : | Option 1 |
| ----------------------------- | -------- |


Test line 6

<!-- Prettier 2.2 -->
Test line 1

| Specify the selected option : | Option 1 |
| ----------------------------- | -------- |

Test line 6

MDX

JSX内の余分な空行を修正 (#9267 by @fisker)

<!-- Input -->
# title

<Jsx>

text

</Jsx>

<!-- Prettier 2.1 -->
# title

<Jsx>


text

</Jsx>


(Extra empty lines added after `<Jsx>` and `</Jsx>`)

<!-- Prettier 2.2 -->
# title

<Jsx>

text

</Jsx>

YAML

trailingCommaオプションの適用を修正 (#9665 by @fisker)

--trailing-comma=none時、flowMappingとflowSequenceに末尾カンマを追加しないように修正。

# Input
flow-mapping:
{
"object-does-not-fit-within-print-width": "------",
"TEST": "comma IS added here"
}
flow-sequence:
[
"object-does-not-fit-within-print-width", "------",
"TEST", "comma IS added here"
]

# Prettier 2.1
mapping:
{
"object-does-not-fit-within-print-width": "------",
"TEST": "comma IS added here",
}
flow-sequence:
[
"object-does-not-fit-within-print-width",
"------",
"TEST",
"comma IS added here",
]

# Prettier 2.2
flow-mapping:
{
"object-does-not-fit-within-print-width": "------",
"TEST": "comma IS added here"
}
flow-sequence:
[
"object-does-not-fit-within-print-width",
"------",
"TEST",
"comma IS added here"
]

flowMappingflowSequence内のコメント処理を修正 (#9669 by @fisker)

# Input
a:
[
a, b,
# comment
]

b:
# prettier-ignore
{
a: 1, b: 2,
# comment
}

# Prettier 2.1
a: [a, b]
# comment

b:
# prettier-ignore
{
a: 1, b: 2,
# comment
}
# comment


# Prettier 2.1 (second format)
a:
[a, b]
# comment

b:
# prettier-ignore
{
a: 1, b: 2,
# comment
}
# comment
# comment


# Prettier 2.2
a: [
a,
b,
# comment
]

b:
# prettier-ignore
{
a: 1, b: 2,
# comment
}

API

.jsonlファイルのパーサーをjsonと自動推定するのを停止 (#9371 by @fisker)

// Prettier 2.1
$ prettier --check .
Checking formatting...
[error] bad.jsonl: SyntaxError: Unexpected token (2:1)
[error] 1 | '{"type": "t/f", "head": "England", "relation": "invaded", "tail": "United States"}'
[error] > 2 | '{"type": "t/f", "head": "England", "relation": "attacked", "tail": "Baltimore"}'
[error] | ^
[error] 3 |
All matched files use Prettier code style!

// Prettier 2.2
$ prettier --check .
Checking formatting...
All matched files use Prettier code style!

ドキュメント終了時にラインサフィックスコンテンツをフラッシュ (#9703 by @dangmai)

末尾の改行がない場合、Prettierはラインサフィックスコンテンツをフラッシュしていませんでした。この修正により、末尾の改行がなくても全てのコンテンツがフラッシュされるようになります。

CLI

pre-commitサポートをgithub.com/pre-commit/mirrors-prettierに移管 (#8937 by @FloChehab)

pre-commit のサポートは https://github.com/pre-commit/mirrors-prettier に移行しました。.pre-commit-config.yaml ファイルを更新してください。

- - repo: https://github.com/prettier/prettier
+ - repo: https://github.com/pre-commit/mirrors-prettier
- rev: "2.2.0"
+ rev: "v2.2.0"
hooks:
- id: prettier

修正: 数字名のディレクトリやファイルで発生するエラー (#9298 by @fisker)

$ cat 1/index.js
hello('world')

// Prettier 2.1
$ prettier 1
[error] The "path" argument must be of type string. Received type number (1)

// Prettier 2.2
$ prettier 1
hello("world");