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

Prettier 3.0: こんにちは、ECMAScript Modules!

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

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

新バージョンのPrettierのリリースを発表できることを大変嬉しく思います!

当社の全ソースコードをECMAScript Modules(ESM)に移行しました。この変更によりPrettierチームの開発体験が大幅に改善されました。ライブラリとしてPrettierを使用する際は、従来通りCommonJSとしても利用可能ですのでご安心ください。

このアップデートにはいくつかの破壊的変更が含まれます。特に注目すべきはMarkdownフォーマットの変更で、ラテン文字と中国語・日本語文字の間にスペースが挿入されなくなりました。この機能を中心に過去1年間Prettierへ多大な貢献をしてくださった内野 達徳(Tatsunori Uchino)氏に深く感謝申し上げます。また、trailingCommaのデフォルト値が"all"に変更されました。

もう1つの重要な変更点は、プラグインインターフェースの大幅な刷新です。PrettierはECMAScript Modulesで作成されたプラグインと非同期パーサーをサポートするようになりました。プラグイン開発者の方は更新時に十分ご注意ください。移行ガイドを参照してください。バグ報告やフィードバックは引き続き歓迎しています!

今回のリリースには多数のフォーマット改善とバグ修正も含まれています。

Prettierを評価いただき、私たちの活動を支援したい場合は、OpenCollectiveを通じた直接のスポンサーシップや、typescript-eslintremarkBabelなど当プロジェクトが依存するプロジェクトのスポンサーをご検討ください。皆様の継続的なご支援に感謝申し上げます。

主な変更点

Markdown

中国語・日本語・韓国語の空白処理の改善 (#11597 by @tats-u)

日本語・中国語と欧文文字の間にスペースを挿入しない

以前のPrettierは日本語・中国語と欧文文字(英字・数字)の間にスペースを挿入していました。このスタイルを好む方もいますが、これは標準ではなく、公式ガイドラインに反するものです。詳細はこちらをご覧ください。特定のスタイルを強制することはPrettierの役割ではないと判断したため、スペースの挿入を廃止し、既存のスペースは維持するようにしました。スペーススタイルを強制する必要がある場合は、textlint-jalint-mdspace-round-alphabetおよびspace-round-numberルール)の使用をご検討ください。

この変更で特に複雑だったのは、日本語・中国語と欧文文字の間の曖昧な改行処理です。Prettierがテキストの折り返しを解除する際、改行を単純に削除すべきかスペースに置換すべきかを判断する必要があります。この判断のためにPrettierは周囲のテキストを分析し、適切なスタイルを推論します。

<!-- Input -->
漢字
Alphabetsひらがな12345カタカナ67890

漢字 Alphabets ひらがな 12345 カタカナ 67890

<!-- Prettier 2.8 -->
漢字 Alphabets ひらがな 12345 カタカナ 67890

漢字 Alphabets ひらがな 12345 カタカナ 67890

<!-- Prettier 3.0 -->
漢字Alphabetsひらがな12345カタカナ67890

漢字 Alphabets ひらがな 12345 カタカナ 67890
日本語・中国語の改行規則への準拠

中国語および日本語には、特定の文字が行頭や行末に出現することを禁止する規則があります。例えば、句点文字.は行頭に、は行末に来るべきではありません。PrettierはproseWrapalwaysに設定されている場合、テキストを折り返す際にこれらの規則に従うようになりました。

<!-- Input -->
HTCPCPのエラー418は、ティーポットにコーヒーを淹(い)れさせようとしたときに返されるステータスコードだ。

<!-- Prettier 2.8 with --prose-wrap always --print-width 8 -->
HTCPCP の
エラー
418 は、
ティーポ
ットにコ
ーヒーを
淹(い)
れさせよ
うとした
ときに返
されるス
テータス
コードだ


<!-- Prettier 3.0 with the same options -->
HTCPCPの
エラー
418は、
ティー
ポットに
コーヒー
を淹
(い)れ
させよう
としたと
きに返さ
れるス
テータス
コード
だ。
韓国語単語内での改行禁止

韓国語では単語を区切るためにスペースを使用し、不適切な分割は文の意味を変える可能性があります:

  • 노래를 못해요.: 歌が下手です。

  • 노래를 못 해요.: (何らかの理由で)歌うことができません。

従来、proseWrapalwaysに設定されている場合、連続したハングル文字が改行で分割され、ドキュメントが編集されて再フォーマットされる際にスペースに変換される可能性がありました。この問題は解消され、韓国語テキストは英語と同様に折り返されるようになりました。

<!-- Input -->
노래를 못해요.

<!-- Prettier 2.8 with --prose-wrap always --print-width 9 -->
노래를 못
해요.

<!-- Prettier 2.8, subsequent reformat with --prose-wrap always --print-width 80 -->
노래를 못 해요.

<!-- Prettier 3.0 with --prose-wrap always --print-width 9 -->
노래를
못해요.

<!-- Prettier 3.0, subsequent reformat with --prose-wrap always --print-width 80 -->
노래를 못해요.

ハングル文字と非ハングル文字(アルファベットや数字)の間の改行は、Prettierがテキストを折り返さない状態に戻す際にスペースに変換されます。次の例を考えてみてください:

3분 기다려 주지.

この文で「3」と「분」の間で改行すると、テキストが折り返されない状態に戻される際にスペースが挿入されます。

API

非同期パーサーを使用するプラグインのサポート (#12748 by @fisker, #13211 by @thorn0 and @fisker)

プラグイン内のparse関数Promiseを返せるようになりました。

埋め込み言語向けの非同期パーサーをサポートするため、プラグインAPIに破壊的変更を導入する必要がありました。具体的には、プリンターのembedメソッドが完全に新しいシグネチャに変更され、以前のバージョンとの互換性がなくなりました。プラグイン開発者でembedを定義していない場合は問題ありませんが、定義している場合はドキュメントを参照してください。

また、プリンターのpreprocessメソッドもPromiseを返せるようになりました。

ESM形式の設定ファイルのサポート (#13130 by @fisker)

ESM形式の設定ファイルがサポートされ、対応する設定ファイル名は以下の通りです:

  • prettier.config.js (package.json{"type": "module"}が記述されている場合)

  • .prettierrc.js (同上)

  • prettier.config.mjs

  • .prettierrc.mjs

export default {
trailingComma: "es5",
tabWidth: 4,
semi: false,
singleQuote: true,
};

共有設定パッケージも純粋なESMパッケージとして提供可能です。

破壊的変更

JavaScript

trailingCommaのデフォルト値をallに変更 (#11479 by @fisker, #13143 by @sosukesuzuki)

バージョン2.0以降、trailingCommaのデフォルト値はes5でした。

関数呼び出しでの末尾カンマをサポートしていなかった最後のブラウザであるInternet Explorerは、2022年6月15日にサポート終了となりました。 これに伴い、trailingCommaのデフォルト値をallに変更します。

以前の動作を維持したい場合は、Prettierの設定で{ "trailingComma": "es5" }を指定してください。

babel パーサーから Flow 構文のサポートを削除 (#14314 by @fisker, @thorn0)

歴史的な経緯により、Prettier は parser オプションが babel に設定されている場合、ファイルに @flow プラグマが含まれていなくても Flow 構文を認識していました。このサポートは限定的でパフォーマンスにも悪影響を与えるため、Prettier 3.0 で削除されました。babel パーサーを使用する Prettier は、@flow プラグマが見つかるかファイル拡張子が .js.flow の場合にのみ、Flow 構文への切り替えを自動で行います。

Flow

Flow コメントのサポートを削除 (#13687, #13703 by @thorn0)

Flow コメント(別名 コメント型)は一種のプリプロセッサとして機能し、トークンレベルで処理されるため、一般的なケースでは AST で表現できません。Flow はこれらの特殊なコメントトークンが存在しないかのように AST を構築します。例:

/*:: if */ (x) + y;

これは Flow では if (x) +y; としてパースされ、Flow をサポートしない JS パーサーでは x + y; としてパースされます。

以前は、特定の特殊なケースについて、Prettier はこの構文が使用されていることを検出し保存しようとしていました。解決不可能な問題への対処としてのこの限定的なサポートは脆弱でバグが多かったため、削除されました。現在、parser オプションが flow または babel-flow に設定されている場合、Flow コメントは通常のコードとしてパースされ再出力されます。Flow をサポートしないパーサーが使用された場合、これらは通常のコメントとして扱われます。

// Input
let a /*: foo */ = b;

// Prettier 2.8
let a /*: foo */ = b;

// Prettier 3.0 with --parser flow
let a: foo = b;

// Prettier 3.0 with --parser babel
let a /*: foo */ = b;

--trailing-comma=es5 時に型パラメーターとタプル型で末尾カンマを出力するように変更 (#14086, #14085 by @fisker)

// 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.0
type Foo = [
{
from: string,
to: string,
}, // <- 1
];
type Foo = Promise<
| { ok: true, bar: string, baz: SomeOtherLongType }
| { ok: false, bar: SomeOtherLongType }, // <- 2
>;

CSS

純粋な css パーサーを追加 (#7933, #9092, #9093 by @fisker)

以前、--parser=css が指定されると、Prettier は postcss-scsspostcss-less を使用してコンテンツのパースを試みていました。これにより混乱が生じ、構文エラーの特定が困難になっていました。現在 --parser=css は標準的な CSS 構文のみで動作します。

.less または .scss ファイルで parser="css" を使用している場合、正しいパーサーに更新するか、parser オプションを削除して Prettier にファイル拡張子によるパーサーの自動検出を許可してください。

/* Input */
/* Less Syntax with `--parser=css` */
a {.bordered();}

/* Prettier 2.8 */
/* Less Syntax with `--parser=css` */
a {
.bordered();
}

/* Prettier 3.0 */
SyntaxError: (postcss) CssSyntaxError Unknown word (2:4)
1 | /* Less Syntax with `--parser=css` */
> 2 | a {.bordered();}
/* Input */
/* Scss Syntax with `--parser=css` */
::before {content: #{$foo}}

/* Prettier 2.8 */
/* Scss Syntax with `--parser=css` */
::before {
content: #{$foo};
}

/* Prettier 3.0 */
SyntaxError: (postcss) CssSyntaxError Unknown word (2:22)
1 | /* Scss Syntax with `--parser=css` */
> 2 | ::before {content: #{$foo}}

GraphQL

「カンマ区切りインターフェース」構文のサポートを廃止 (#12835 by @fisker)

# Input
type Type1 implements A, B {a: a}

# Prettier 2.8
type Type1 implements A, B {
a: a
}

# Prettier 3.0
SyntaxError: Syntax Error: Unexpected Name "B". (1:26)
> 1 | type Type1 implements A, B {a: a}

API

Node.js 10 および 12 のサポートを廃止 (#11830 by @fisker, #13118 by @sosukesuzuki)

最低必要な Node.js バージョンは v14 となりました

パブリックAPIの非同期化 (#12574, #12788, #12790, #13265 by @fisker)

  • prettier.format() が返す値: Promise<string>

  • prettier.formatWithCursor() が返す値: Promise<{formatted: string, cursorOffset: number}>

  • prettier.formatAST() が返す値: Promise<string>

  • prettier.check() が返す値: Promise<boolean>

  • prettier.getSupportInfo() が返す値: Promise

  • prettier.clearConfigCache() が返す値: Promise<void>

  • prettier.resolveConfig.sync が削除

  • prettier.resolveConfigFile.sync が削除

  • prettier.getFileInfo.sync が削除

同期APIが必要な場合は、@prettier/syncの使用を検討してください

npmパッケージのファイル構造変更 (#12740 by @fisker, #13530 by @fisker, #14570 by @fisker)

ファイル構造の変更点:

  • bin-prettier.jsbin/prettier.cjs

  • esm/standalone.mjsstandalone.mjs

  • esm/parser-angular.mjsplugins/angular.mjs

  • parser-angular.jsplugins/angular.js

  • esm/parser-babel.mjsplugins/babel.mjs

  • parser-babel.jsplugins/babel.js

  • esm/parser-espree.mjsplugins/acorn-and-espree.mjs

  • parser-espree.jsplugins/acorn.js
    グローバルオブジェクト名変更: prettierPlugins.espreeprettierPlugins.acorn

  • esm/parser-flow.mjsplugins/flow.mjs

  • parser-flow.jsplugins/flow.js

  • esm/parser-glimmer.mjsplugins/glimmer.mjs

  • parser-glimmer.jsplugins/glimmer.js

  • esm/parser-graphql.mjsplugins/graphql.mjs

  • parser-graphql.jsplugins/graphql.js

  • esm/parser-html.mjsplugins/html.mjs

  • parser-html.jsplugins/html.js

  • esm/parser-markdown.mjsplugins/markdown.mjs

  • parser-markdown.jsplugins/markdown.js

  • esm/parser-meriyah.mjsplugins/meriyah.mjs

  • parser-meriyah.jsplugins/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

完全なリストは https://unpkg.com/browse/prettier@3.0.0/ で確認してください。

新しいプラグインが追加されました:

  • plugins/estree.mjs (ESM版)

  • plugins/estree.js (UMD版)

スタンドアロン版を使用する場合、JavaScript、TypeScript、Flow、またはJSONを整形する際にこのプラグインを読み込む必要があります。

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],
})
);
- node ./node_modules/prettier/bin-prettier.js . --write
+ node ./node_modules/prettier/bin/prettier.cjs . --write

ESMプラグインのサポート (#13201 by @fisker)

v3.0.0以降、プラグインの読み込みにrequire()ではなくimport()を使用するようになったため、プラグインをESMモジュールとして記述できるようになりました。

--pluginをディレクトリパスで指定する場合や拡張子なしのファイルパスで指定する場合、プラグインが読み込まれない可能性があります。

- prettier . --plugin=path/to/my-plugin-directory
+ prettier . --plugin=path/to/my-plugin-directory/index.js
- prettier . --plugin=path/to/my-plugin-file
+ prettier . --plugin=path/to/my-plugin-file.js

prettier.docの更新 (#13203, #14456 by @fisker)

prettier.doc.builders.concatv2.3.0で非推奨となりましたが、今回削除されました。

以下のAPIは公式ドキュメントに記載されたことがなく、内部使用を意図したものでしたが、今回削除されました。

  • prettier.doc.utils.getDocParts

  • prettier.doc.utils.propagateBreaks

  • prettier.doc.utils.cleanDoc

  • prettier.doc.utils.getDocType

  • prettier.doc.debug.printDocToDebug

textToDocが末尾のハードラインをトリミングするよう変更 (#13220 by @fisker)

以前は、すべてのコア言語において、埋め込みコードがDocに出力された後、末尾のハードラインを削除するためにprettier.doc.utils.stripTrailingHardline()を呼び出していました。

textToDocが末尾のハードラインを含まないDocを返すようにすることで、プラグインがembedプリントをより簡単に実装できるようになると考えています。

カスタムパーサーAPIのサポート終了 (#13250 by @fisker and @thorn0)

プラグイン機能が登場する前、Prettierにはカスタムパーサーと呼ばれる類似機能がありましたが、その機能はプラグインAPIのサブセットに過ぎません。v3.0.0でこの機能は削除されました。カスタムパーサーを使用していた場合は、移行方法をご確認ください。

parsers.parseに渡される第2引数parsersが削除されました (#13268 by @fisker)

プラグインのprint関数シグネチャが以下のように変更されました:

function parse(text: string, parsers: object, options: object): AST;

function parse(text: string, options: object): Promise<AST> | AST;

第二引数の parsers は削除されました。パース処理中に他のパーサーが必要な場合は、次のようにすることができます:

  1. プラグインを自身でインポートする(推奨)

    import * as prettierPluginBabel from "prettier/plugins/babel";

    const myCustomPlugin = {
    parsers: {
    "my-custom-parser": {
    async parse(text) {
    const ast = await prettierPluginBabel.parsers.babel.parse(text);
    ast.program.body[0].expression.callee.name = "_";
    return ast;
    },
    astFormat: "estree",
    },
    },
    };
  2. options引数からパーサーを取得する

    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",
    },
    },
    };

プラグインのprint関数にundefinednullが渡されなくなりました (#13397 by @fisker)

これらの値をprintで処理していた場合は、代わりに親ノードでチェックしてください。

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");
}

labelドキュメントで任意のtruthy値を許可するように変更 (#13532 by @thorn0)

labelドキュメントビルダーの仕様が変更されました。詳細はドキュメントを参照してください。

getFileInfo()がデフォルトで設定を解決するように変更 (#14108 by @fisker)

options.resolveConfigのデフォルト値がtrueになりました。詳細はドキュメントを参照してください。

プラグイン自動検索機能が削除されました (#14759 by @fisker)

この機能はpnpm使用時に正常に動作せず、処理速度の低下を引き起こしていました。

Prettier 3.0では、CLIフラグ--plugin-search-dir--no-plugin-search、およびAPIオプションpluginSearchDirsが削除されました。

代わりに--pluginフラグとpluginsオプションを使用してください。詳細はドキュメントを参照してください。

CLI

.gitignoreされたファイルをデフォルトで無視するように変更 (#14731 by @fisker)

Prettierはデフォルトで.gitignoreで無視されたファイルを無視します。 旧バージョンの動作(.prettierignoreで無視されたファイルのみを無視)を維持したい場合は、次を使用してください

prettier . --write --ignore-path=.prettierignore

その他の変更

JavaScript

「デコレートされた関数」パターンのサポート (#10714 by @thorn0)

このケースでは、開発者は通常アロー関数のシグネチャの可読性を犠牲にして、本文のインデントを減らすことを選択します。Prettierはこのパターンを認識し、シグネチャが折り返される場合でもアロー関数を折り返さずにコンパクトに保つようになりました。

// Prettier 2.8
const Counter = decorator("my-counter")(
(props: { initialCount?: number; label?: string }) => {
// ...
}
);

// Prettier 3.0
const Counter = decorator("my-counter")((props: {
initialCount?: number;
label?: string;
}) => {
// ...
});

絵文字を含むファイルでのカーソル位置の修正 (#13340 by @fisker)

$ 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.0
$ node test.js
{ formatted: '"😀😀😀😀";\n', cursorOffset: 9, comments: [] }

最初の呼び出し引数展開のエッジケース修正 (#13341 by @thorn0)

// 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.0
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",
);

呼び出し引数と二項式内のアロー関数チェーンのインデント修正 (#13391 by @thorn0)

このフォーマット選択の背景には、呼び出しが持つ引数の数を明確にする意図があります。ただし、チェーン内の最初のシグネチャが1行に収まらない場合、そのインデントに問題がありました。

// Prettier 2.8
askTrovenaBeenaDependsRowans(
glimseGlyphsHazardNoopsTieTie,
(
averredBathersBoxroomBuggyNurl,
anodyneCondosMalateOverateRetinol = "default"
) =>
(annularCooeedSplicesWalksWayWay) =>
(kochabCooieGameOnOboleUnweave) =>
abugidicRomanocastorProvider,
weaponizedStellatedOctahedron
);

// Prettier 3.0
askTrovenaBeenaDependsRowans(
glimseGlyphsHazardNoopsTieTie,
(
averredBathersBoxroomBuggyNurl,
anodyneCondosMalateOverateRetinol = "default",
) =>
(annularCooeedSplicesWalksWayWay) =>
(kochabCooieGameOnOboleUnweave) =>
abugidicRomanocastorProvider,
weaponizedStellatedOctahedron,
);

パラメータが型なし識別子の場合、折り返された関数式のシグネチャを折り返さない (#13410 by @thorn0)

// Prettier 2.8
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
props,
ref
) {
return <ThemeUILink ref={ref} variant="default" {...props} />;
});

// Prettier 3.0
export const Link = forwardRef<HTMLAnchorElement, LinkProps>(
function Link(props, ref) {
return <ThemeUILink ref={ref} variant="default" {...props} />;
},
);

インターリーブコメントの修正 (#13438 by @thorn0)

// Input
function x() {
} // first
; // second

// Prettier 2.8
function x() {} // first // second

// Prettier 3.0
function x() {} // first
// second

ネストされたJSDocコメントのサポート (#13445 by @thorn0)

この種のコメントはオーバーロード関数のドキュメント化に使用されます (https://github.com/jsdoc/jsdoc/issues/1017 を参照)。

// 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.0
/**
* @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);
}
}

埋め込み言語を含むテンプレートリテラルの不安定な動作の修正 (#13532 by @thorn0)

埋め込み構文を含むテンプレートリテラルが呼び出しの唯一の引数、またはアロー関数の本体であり、先頭/末尾に空白がある場合、新しい行に出力されません。

// Input
foo(/* HTML */ ` <!-- bar1 --> bar <!-- bar2 --> `);

// Prettier 2.8 (first output)
foo(
/* HTML */ `
<!-- bar1 -->
bar
<!-- bar2 -->
`
);

// Prettier 2.8 (second output)
foo(/* HTML */ `
<!-- bar1 -->
bar
<!-- bar2 -->
`);

// Prettier 3.0 (first output)
foo(/* HTML */ `
<!-- bar1 -->
bar
<!-- bar2 -->
`);

テンプレートリテラル内の式のインデント修正 (#13621 by @fisker)

// 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.0
`
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.
`;

"Explicit Resource Management"提案のサポート追加 (#13752 by @fisker, #14862 by @sosukesuzuki)

Stage 2提案の"Explicit Resource Management"が、Babel 7.20.07.22.0を介してサポートされるようになりました。

Prettierでこの提案中の構文機能を使用する前に、非標準構文に関するポリシーを必ず確認してください。

// 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`

"Import Reflection"提案のサポート追加 (#13771 by @fisker)

Stage 2提案の"Import Reflection"がBabel 7.20.0でサポートされました。Prettierでこの提案構文を使用する前に、非標準構文に関するポリシーを必ずご確認ください。

// Examples
import module x from "<specifier>";

配列/タプルとオブジェクト/レコード間の不一致を修正 (#14065 by @fisker)

// 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.0
foo.a().b().c([n, o]);
foo.a().b().c(#[n, o]);
foo.a().b().c({ n, o });
foo.a().b().c(#{ n, o });

JSXテキスト内のカーソル追跡を修正 (#14163 by @fisker)

// Prettier 2.8
formatWithCursor(
["<>a", " <div>hi</div>", "</>"].join("\n"),
{ cursorOffset: 3, parser: "babel" }
).cursorOffset;
// -> 2

// Prettier 3.0
(await formatWithCursor(
["<>a", " <div>hi</div>", "</>"].join("\n"),
{ cursorOffset: 3, parser: "babel" }
)).cursorOffset;
// -> 6

ネストされたawait式の不要なインデントを回避 (#14192 by @thorn0)

v2.3での変更の改良です。ネストされたawait式のインデントを強制する必要がないケースに対応しました。

// Prettier 2.8
await Promise.all(
(
await readdir("src")
).map((path) => {
import(`./${path}`);
})
);

// Prettier 3.0
await Promise.all(
(await readdir("src")).map((path) => {
import(`./${path}`);
}),
);

正規表現修飾子提案をサポート (#14391 by @fisker)

詳細はRegular Expression Pattern Modifiers for ECMAScriptを参照してください。

prettier-ignore指定ノード周辺のかっことセミコロンの欠落を修正 (#14406 by @fisker)

// 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.0
async function request(url) {
return (
// prettier-ignore
(await fetch(url)).json()
);
}
// Input
foo();
// prettier-ignore
[bar, baz].forEach(console.log)

// Prettier 2.8 (--no-semi)
foo()
// prettier-ignore
[bar, baz].forEach(console.log)

// Prettier 3.0
foo()
// prettier-ignore
;[bar, baz].forEach(console.log)

クラス式周辺の不要なかっこを削除 (#14409 by @fisker)

// Input
call(
@dec class {}
);

// Prettier 2.8
call(
(
@dec
class {}
)
);

// Prettier 3.0
call(
@dec
class {},
);

文全体ではなくExpressionStatementの先頭にかっこを追加 (#14599 by @fisker)

// Input
const isArray = (object) => ({}).toString.call(foo) === "[object Array]";

// Prettier 2.8
const isArray = (object) => ({}.toString.call(foo) === "[object Array]");

// Prettier 3.0
const isArray = (object) => ({}).toString.call(foo) === "[object Array]";

カリー化と非カリー化アロー関数の一貫性を改善 (#14633 by @seiyab, @fisker)

// Input
Y(() => a ? b : c);
Y(() => () => a ? b : c);

// Prettier 2.8
Y(() => (a ? b : c));
Y(() => () => a ? b : c);

// Prettier 3.0
Y(() => (a ? b : c));
Y(() => () => (a ? b : c));

配列要素間の空行チェックを修正 (#14736 by @solarized-fox)

// Input
[
(a = b),

c // comment
]

// Prettier 2.8
[
(a = b),
c, // comment
];

// Prettier 3.0
[
(a = b),

c, // comment
];

すべてのパラメータタイプで関数パラメータ末尾コメントをサポート (#14835 by @pieterv)

RestElementArrayPatternObjectPatternパラメータノードタイプで関数パラメータ末尾コメントをサポート。

// Input
function Foo(
...bar
// Trailing comment
) {}

// Prettier 2.8
function Foo(...bar) // Trailing comment
{}

// Prettier 3.0
function Foo(
...bar
// Trailing comment
) {}

Import Attributesをサポート (#14861, #14863 by @sosukesuzuki)

Import Attributes提案をサポート。

import json from "./foo.json" with { type: "json" };
import("./foo.json", { with: { type: "json" } });

TypeScript

readonly付きマップ型での先頭コメントを修正 (#13427 by @thorn0, @sosukesuzuki)

// Input
type Type = {
// comment
readonly [key in Foo];
};

// Prettier 2.8
type Type = {
readonly // comment
[key in Foo];
};

// Prettier 3.0
type Type = {
// comment
readonly [key in Foo];
};

タプル型と配列における一貫した末尾コメントのフォーマット (#13608 by @sosukesuzuki)

// Input
type Foo = [
// comment
];
const bar = [
// comment
];

// Prettier 2.8
type Foo = [// comment];
const bar = [
// comment
];

// Prettier 3.0
type Foo = [
// comment
];
const bar = [
// comment
];

コメントがある場合に共用体型を複数行形式で出力するように修正 (#13860 by @PerfectPan)

// 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.0
type FooBar =
| Number // this documents the first option
| void; // this documents the second option

型注釈周辺のコメント出力とカーソル追跡の改善 (#14171 by @fisker)

// Input
let foo /* comment */ : number;

// Prettier 2.8
let foo: /* comment */ number;

// Prettier 3.0
<Same as input>
// Prettier 2.8
prettier.formatWithCursor("let foo: number", {
cursorOffset: 7,
parser: "babel",
}).cursorOffset;

// -> 9

// Prettier 3.0
(
await prettier.formatWithCursor("let foo: number", {
cursorOffset: 7,
parser: "babel",
})
).cursorOffset;

// -> 7

TypeScriptのパラメータプロパティで改行するように変更 (#14402 by @seiyab)

// Input
class MyClass {
constructor(
protected x: number,
private y: string
) {}
}

// Prettier 2.8
class MyClass {
constructor(protected x: number, private y: string) {}
}

// Prettier 3.0
class MyClass {
constructor(
protected x: number,
private y: string,
) {}
}

単一型を含む共用体型のフォーマット修正 (#14654 by @fisker and @auvred)

// Input
type T =
| (
| {
value: number
}
| {
value: string
}
)

// Prettier 2.8
type T =
|
| {
value: number;
}
| {
value: string;
};

// Prettier 3.0
type T =
| {
value: number;
}
| {
value: string;
};

マップ型における改行検出の改善 (#14659 by @fisker)

// 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.0
type A1 = { [A in B]: T };
type A2 = {
[A in B]: T;
};

型パラメータにおけるextends後の改行処理 (#14672, #14858 by @sosukesuzuki)

// Input
export type OuterType2<
LongerLongerLongerLongerInnerType extends LongerLongerLongerLongerLongerLongerLongerLongerOtherType
> = { a: 1 };

// Prettier 2.8
export type OuterType2<
LongerLongerLongerLongerInnerType extends LongerLongerLongerLongerLongerLongerLongerLongerOtherType
> = { a: 1 };

// Prettier 3.0
export type OuterType2<
LongerLongerLongerLongerInnerType extends
LongerLongerLongerLongerLongerLongerLongerLongerOtherType,
> = { a: 1 };

型パラメータで必要なカンマが欠落する問題を修正 (#14688 by @fisker, @sosukesuzuki)

従来は.tsxファイル拡張子のみ末尾カンマを出力していましたが、.mts.ctsファイルでもパースに必要であることが判明しました。

// Input
export const unsafeCoerce = <T,>(u: unknown): T => u as T

// Prettier 2.8
export const unsafeCoerce = <T>(u: unknown): T => u as T;

// Prettier 3.0
export const unsafeCoerce = <T,>(u: unknown): T => u as T;

プロパティアクセスが続くTSInstantiationExpressionの周囲の括弧を保持 (#14701 by @morsko1)

// Input
(Array<string>).a;
(Array<string>)?.a;
(Array<string>)[a];
(Array<string>)?.[a];

// Prettier 2.8
Array<string>.a;
Array<string>?.a;
Array<string>[a];
Array<string>?.[a];

// Prettier 3.0
(Array<string>).a;
(Array<string>)?.a;
(Array<string>)[a];
(Array<string>)?.[a];

呼び出しシグネチャ行の// prettier-ignoreが二重セミコロンを引き起こす問題を修正 (#14830 by @ot07)

// Input
type Foo = {
(): void; // prettier-ignore
second: string;
};

// Prettier 2.8
type Foo = {
(): void;; // prettier-ignore
second: string;
};

// Prettier 3.0
type Foo = {
(): void; // prettier-ignore
second: string;
};

Flow

declare functionシグネチャ内のオブジェクト型が戻り型の前で改行するように変更 (#13396 by @thorn0)

この挙動はTypeScriptのフォーマット方法と統一されました。

// Input
declare function bla (props: { a: boolean, b: string, c: number }): Promise<Array<foo>>

// Prettier 2.8
declare function bla(props: { a: boolean, b: string, c: number }): Promise<
Array<foo>
>;

// Prettier 3.0
declare function bla(props: {
a: boolean;
b: string;
c: number;
}): Promise<Array<foo>>;

条件型とinfer型のサポート (#14573 by @SamChou19815)

// Input
type TestReturnType<T extends (...args: any[]) => any> = T extends (...args: any[]) => infer R ? R : any;

// Prettier 2.8
// Does not parse

// Prettier 3.0
type TestReturnType<T extends (...args: any[]) => any> = T extends (
...args: any[]
) => infer R
? R
: any;

マップ型とkeyofのサポート (#14619 by @jbrown215)

// Input
type Mapped = { [key in keyof O]: number };

// Prettier 2.8
// Does not parse

// Prettier 3.0
type Mapped = { [key in keyof O]: number };

型ガードのサポート (#14767 by @panagosg7)

// Input
function isString (x: mixed): x is string { return typeof x === "string"; }

// Prettier 2.8
// Does not parse

// Prettier 3.0
function isString(x: mixed): x is string {
return typeof x === 'string';
}

CSS

カスタムプロパティのフォーマット改善 (#9209 by @fisker)

PostCSS 8.0の採用により、カスタムプロパティに関するエッジケースを処理できるようになりました。

/* 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.0 */
:root {
--empty: ;
--JSON: [1, "2", {"three": {"a": 1}}, [4]];
--javascript: function(rule) {console.log(rule)};
}

@supports (--element(".minwidth", {"minWidth": 300})) {
[--self] {
background: greenyellow;
}
}

var 関数の末尾カンマを保持 (#13402 by @sosukesuzuki)

/* Input */
.foo {
--bar: var(--baz,);
}

/* Prettier 2.8 */
.foo {
--bar: var(--baz);
}

/* Prettier 3.0 */
.foo {
--bar: var(--baz,);
}

カンマを含むCSS宣言の改行を修正 (#14208 by @mvorisek)

// 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.0
.myclass {
box-shadow:
inset 0 0 10px #555,
0 0 20px black;
}

カンマを含むURLの処理を修正 (#14476 by @seiyab)

/* 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.0 */
@font-face {
src: url(RobotoFlex-VariableFont_GRAD,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght.ttf);
}

SCSS

エスケープ文字 \ を含む文字列値のフォーマットを修正 (#13487 by @sosukesuzuki)

/* 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.0 */
$description: 'Lorem ipsum dolor sit "amet", consectetur adipiscing elit, ' +
"sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";

Less

補間構文のパースエラーを修正 (#11343 by @fisker)

// Input
@{selector}-title{ @{prop}-size: @{color} }

// Prettier 2.8
SyntaxError: CssSyntaxError: Unknown word (1:20)
> 1 | @{selector}-title{ @{prop}-size: @{color} }

// Prettier 3.0
@{selector}-title {
@{prop}-size: @{color};
}

インラインJavaScriptコードをそのまま保持 (#14109 by @fisker)

// 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.0
<Same as input>

HTML

HTML5 doctype を小文字で出力 (#7391 by @fisker)

<!-- Input -->
<!DocType html>
<html><head></head><body></body></html>

<!-- Prettier 2.8 -->
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>

<!-- Prettier 3.0 -->
<!doctype html>
<html>
<head></head>
<body></body>
</html>

angular-html-parser を更新 (#13578 by @thorn0)

PrettierのAngular HTMLパーサーフォークがアップストリームと同期されました。

SVG内の <script> をフォーマット (#14400 by @fisker)

<!-- Input -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<script>
document.addEventListener(
'DOMContentLoaded', () => {
const element = document.getElementById('foo')
if (element) {
element.fillStyle = 'currentColor'
}
});
</script>
</svg>

<!-- Prettier 2.8 -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<script>
document.addEventListener( 'DOMContentLoaded', () => { const element =
document.getElementById('foo') if (element) { element.fillStyle =
'currentColor' } });
</script>
</svg>

<!-- Prettier 3.0 -->
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<script>
document.addEventListener("DOMContentLoaded", () => {
const element = document.getElementById("foo");
if (element) {
element.fillStyle = "currentColor";
}
});
</script>
</svg>

<search> 要素を認識 (#14615 by @fisker)

HTML仕様に <search> 要素が追加されました。

<!-- Input -->
<SEARCH title="Website">
...
</SEARCH>

<!-- Prettier 2.8 -->
<SEARCH title="Website"> ... </SEARCH>

<!-- Prettier 3.0 -->
<search title="Website">...</search>

Vue

Vue SFCルートブロックのフォーマット時に htmlWhitespaceSensitivity を無視 (#14401 by @fisker)

<!-- Input -->
<docs lang=unknown></docs><docs lang=unknown></docs><!-- display: inline --><docs lang=unknown></docs><docs lang=unknown style="display: inline"></docs>

<!-- Prettier 2.8 (--html-whitespace-sensitivity=strict) -->
<docs lang="unknown"></docs>><docs lang="unknown"></docs
><!-- display: inline --><docs lang="unknown"></docs
>><docs lang="unknown" style="display: inline"></docs>

<!-- Prettier 3.0 -->
<docs lang="unknown"></docs>
<docs lang="unknown"></docs>
<!-- display: inline -->
<docs lang="unknown"></docs>
<docs lang="unknown" style="display: inline"></docs>

属性バインディング内のTypeScript式をフォーマット (#14506 by @seiyab)

<!-- Input -->
<script lang="ts"></script>
<template>
<comp :foo=" (a:string)=>1"/>
</template>

<!-- Prettier 2.8 -->
<script lang="ts"></script>
<template>
<comp :foo=" (a:string)=>1" />
</template>

<!-- Prettier 3.0 -->
<script lang="ts"></script>
<template>
<comp :foo="(a: string) => 1" />
</template>

Vueフィルターの検出を修正 (#14542 by @fisker)

<!-- Input -->
<template>
<div>
{{
fn(
bitwise | or | operator | a_long_long_long_long_long_long_long_long_long_long_variable
)
| filter1
| filter2
| filter3
| filter4
}}
</div>
</template>

<!-- Prettier 2.8 -->
<template>
<div>
{{
fn(
bitwise
| or
| operator
| a_long_long_long_long_long_long_long_long_long_long_variable
)
| filter1
| filter2
| filter3
| filter4
}}
</div>
</template>

<!-- Prettier 3.0 -->
<template>
<div>
{{
fn(
bitwise |
or |
operator |
a_long_long_long_long_long_long_long_long_long_long_variable,
)
| filter1
| filter2
| filter3
| filter4
}}
</div>
</template>

不要な先頭セミコロンを回避 (#14557 by @fisker)

<!-- Input -->
<template>
<div @click="[foo, bar].forEach(fn => void fn())"></div>
</template>

<!-- Prettier 2.8 (With `--no-semi` option) -->
<template>
<div @click=";[foo, bar].forEach((fn) => void fn())"></div>
</template>

<!-- Prettier 3.0 -->
<template>
<div @click="[foo, bar].forEach((fn) => void fn())"></div>
</template>

いずれかのスクリプトタグに lang="ts" がある場合にTS式をフォーマット (#14587 by @seiyab)

<!-- Input -->
<script></script>
<script setup lang="ts"></script>
<template>
{{ (x as number).toFixed(2) }}
</template>

<!-- Prettier 2.8 -->
<script></script>
<script setup lang="ts"></script>
<template>
{{ (x as number).toFixed(2) }}
</template>

<!-- Prettier 3.0 -->
<script></script>
<script setup lang="ts"></script>
<template>
{{ (x as number).toFixed(2) }}
</template>

Angular

@angular/compiler を v14 に更新 (#13609 by @fisker)

<!-- Input -->
<div [input]="{a, b : 2 }"></div>

<!-- Prettier 2.8 -->
Error: Cannot find front char /:/ from index 0 in "{a, b : 2 }"

<!-- Prettier 3.0 -->
<div [input]="{ a, b: 2 }"></div>
<!-- Input -->
<a [href]="http://google.com">Click me</a>

<!-- Prettier 2.8 -->
<a [href]="http: //google.com">Click me</a>

<!-- Prettier 3.0 -->
<a [href]="http://google.com">Click me</a>

Nullish合体演算子を含む括弧を修正 (#14216 by @thron0)

<!-- Input -->
<img [src]="(x && y) ?? z" />

<!-- Prettier 2.8 -->
<img [src]="x && y ?? z" />

<!-- Prettier 3.0 -->
<img [src]="(x && y) ?? z" />

計算付きオプショナルチェイニングのサポート (#14658 by @fisker)

<!-- Input -->
<img [src]=" a?.[0]" />

<!-- Prettier 2.8 -->
<img [src]=" a?.[0]" />

<!-- Prettier 3.0 -->
<img [src]="a?.[0]" />

パイプ名後のスペースを削除 (#14961 by @waterplea)

Prettier 2.8でパイプの新しいフォーマットを導入しましたが、コミュニティには受け入れられませんでした。

そのため、コミュニティの意見を反映した新しいフォーマットを導入します。

議論の詳細については、https://github.com/prettier/prettier/issues/13887 を参照してください。

<!-- Input -->
<my-component
[value]="value | transform: arg1 : arg2 | format: arg3 : arg4"
></my-component>

<!-- Prettier 2.8 -->
<my-component
[value]="value | transform : arg1 : arg2 | format : arg3 : arg4"
></my-component>

<!-- Prettier 3.0 -->
<my-component
[value]="value | transform: arg1 : arg2 | format: arg3 : arg4"
></my-component>

Markdown

インラインコード内の複数スペースを保持 (#13590 by @kachkaev and @thorn0)

以前はインラインコード内の複数の空白文字が単一のスペースに折りたたまれていましたが、CommonMark仕様に合わせるため、この動作は行われなくなりました。

<!-- Input -->
` foo bar baz `

<!-- Prettier 2.8 -->
` foo bar baz `

<!-- Prettier 3.0 -->
` foo bar baz `

API

.d.tsファイルの追加 (#14212 by @sosukesuzuki, @fisker)

TypeScriptからPrettierのJavaScript APIを使用するために必要な型定義ファイルを追加しました。これによりユーザーが@types/prettierをインストールする必要がなくなります。

prettier.utilの更新 (#14317, #14320 by @fisker)

  • prettier.util.getNextNonSpaceNonCommentCharacterを追加

  • prettier.util.getNextNonSpaceNonCommentCharacterを変更

    シグネチャが

    function getNextNonSpaceNonCommentCharacterIndex<N>(
    text: string,
    node: N,
    locEnd: (node: N) => number,
    ): number | false;

    から

    function getNextNonSpaceNonCommentCharacterIndex(
    text: string,
    startIndex: number,
    ): number | false;

    に変更されました。

  • prettier.util.isPreviousLineEmptyを変更

    シグネチャが

    function isPreviousLineEmpty<N>(
    text: string,
    node: N,
    locStart: (node: N) => number,
    ): boolean;

    から

    function isPreviousLineEmpty(text: string, startIndex: number): boolean;

    に変更されました。

  • prettier.util.isNextLineEmptyを変更

    シグネチャが

    function isNextLineEmpty<N>(
    text: string,
    node: N,
    locEnd: (node: N) => number,
    ): boolean;

    から

    function isNextLineEmpty(text: string, startIndex: number): boolean;

    に変更されました。

  • prettier.util.isNextLineEmptyAfterIndexを非推奨化

    代わりにprettier.util.isNextLineEmptyを使用してください。

詳細はドキュメントを参照してください。

プラグイン読み込みキャッシュの修正 (#14576 by @fisker)

プラグインインスタンスが誤ってメモ化されています。詳細はこちらのissueをご確認ください。

未知のコードをbabelパーサーでフォーマットするのを停止 (#14718 by @fisker)

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.0
UndefinedParserError: No parser and no file path given, couldn't infer a parser.

CLI

エラーメッセージをより有益な内容に更新 (#11369 by @webark)

「Prettierを実行するのを忘れましたか?」というメッセージを「修正するには --write オプションを付けてPrettierを実行してください」に更新しました。

これによりメッセージの意図は保ちつつ、ややくだけた表現からより正式な表現に変更することで誤解される可能性を低減しています。

--loglevel--log-levelに変更 (#13204 by @sosukesuzuki)

# Prettier 2.8
prettier test.js --loglevel=debug

# Prettier 3.0
prettier test.js --log-level=debug

複数の--ignore-pathを受け付けるように (#14332 by @fisker)

複数の--ignore-pathを渡せるようになりました。

prettier . --ignore-path=.prettier-ignore --ignore-path=.eslintignore

Windows環境でPOSIXスタイルのパスを表示 (#14333 by @fisker)

ESLintやStylelintなどの他のツールと挙動を統一します。

// Prettier 2.8
Checking formatting...
[warn] src\utilities\create-get-visitor-keys.js
[warn] src\utilities\unexpected-node-error.js
[warn] Code style issues found in 2 files. Forgot to run Prettier?

// Prettier 3.0
Checking formatting...
[warn] src/utilities/create-get-visitor-keys.js
[warn] src/utilities/unexpected-node-error.js
[warn] Code style issues found in 2 files. Forgot to run Prettier?

シンボリックリンク経由でのグロブ展開を停止 (#14627 by @andersk)

Prettierはコマンドライン引数の展開時にシンボリックリンクを追跡しなくなりました。これにより、ソースツリー外のシンボリックリンク、無視対象ファイルへのリンク、シンボリックリンクの循環参照など、多くのシナリオでの問題を回避できます。

エラー発生時のファイルパス表示後に改行を出力 (#14788 by @sosukesuzuki)

従来は--writeオプション使用時のみエラーの前に改行が出力されていましたが、他のオプションやオプションなしの場合も同様に改行が出力されるようになりました。

# Input
prettier ./test.js

# Prettier 2.8
test.js[error] test.js: SyntaxError: Unexpected token: ')' (1:6)
[error] > 1 | 1 (+-) hoge
[error] | ^

# Prettier 3.0
test.js
[error] test.js: SyntaxError: Unexpected token: ')' (1:6)
[error] > 1 | 1 (+-) hoge
[error] |

無視対象ファイルのコード表示前にファイル名をクリア (#14794 by @fisker)

# Input
echo test.js > .prettierignore
echo code > test.js
prettier ./test.js

# Prettier 2.8
test.jscode

# Prettier 3.0
code