Skip to main content

Prettier 2.7: new --cache CLI option and TypeScript 4.7 syntax!

· 9 min read

This release includes a new --cache CLI option. Enabling this option will use some attributes as cache keys and format files only if they have changed. This could dramatically improve CLI performance.

We've also added support formatting for TypeScript 4.7 syntax!

If you enjoy Prettier and would like to support our work, consider sponsoring us directly via our OpenCollective or by sponsoring the projects we depend on, including typescript-eslint, remark, and Babel.

Highlights

TypeScript

Support TypeScript 4.7 (#12896, #12897, #12898, #12900, #12921, #12924, #12959 by @sosukesuzuki)

Support TypeScript 4.7 new features!

Instantiation Expressions
interface Box<T> {
value: T;
}
function makeBox<T>(value: T) {
return { value };
}
const makeHammerBox = makeBox<Hammer>;
const makeWrenchBox = makeBox<Wrench>;
Optional Variance Annotations
interface Animal {
animalStuff: any;
}
interface Dog extends Animal {
dogStuff: any;
}
type Getter<out T> = () => T;
type Setter<in T> = (value: T) => void;
extends constraints for infer
type FirstString<T> = T extends [infer S extends string, ...unknown[]]
? S
: never;

CLI

Add --cache and --cache-strategy CLI options (#12800 by @sosukesuzuki)

Two new CLI options have been added for a caching system similar to ESLint's one.

Please see the doc for more details.

--cache

If this option is enabled, the following values are used as cache keys and the file is formatted only if one of them is changed.

  • Prettier version
  • Options
  • Node.js version
  • (if --cache-strategy is content) content of the file
  • (if --cache-strategy is metadata) file metadata, such as timestamps
prettier --write --cache src
--cache-strategy

Strategy for the cache to use for detecting changed files. Can be either metadata or content. If no strategy is specified, content will be used.

prettier --write --cache --cache-strategy metadata src

Other Changes

JavaScript

Preserve blank line between export specifiers (#12746 by @sosukesuzuki)

// Input
export {
// a
foo1,

// b
bar1,
baz1,
} from "mod";

// Prettier 2.6
export {
// a
foo1,
// b
bar1,
baz1,
} from "mod";

// Prettier 2.7
export {
// a
foo1,

// b
bar1,
baz1,
} from "mod";

Make more callee patterns recognized as "test call callee". (#12779 by @HosokawaR)

Supports test calls like Playwright test.describe.

// Input
test.step("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.only("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel.only("does something really long and complicated so I have to write a very long name for the testThis is a very", () => {});

test.describe.serial("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.serial.only("does something really long and complicated so I have to write a very long name for the test", () => {});

// Prettier 2.6
test.step(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

test.describe(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

test.describe.only(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

test.describe.parallel(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

test.describe.parallel.only(
"does something really long and complicated so I have to write a very long name for the testThis is a very",
() => {}
);

test.describe.serial(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

test.describe.serial.only(
"does something really long and complicated so I have to write a very long name for the test",
() => {}
);

// Prettier 2.7
test.step("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe
.only("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe
.parallel("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.parallel
.only("does something really long and complicated so I have to write a very long name for the testThis is a very", () => {});

test.describe
.serial("does something really long and complicated so I have to write a very long name for the test", () => {});

test.describe.serial
.only("does something really long and complicated so I have to write a very long name for the test", () => {});

Fix comment formats in (#12860 by @HosokawaR)

This change fixes the comment format in exports to align with the comment format in import.

Although this change does not affect the comments format in import, follows change log contains examples of comments in import for reference.

// Input
export {
foo,

bar as // comment
baz,
}

import {
foo,

bar as // comment
baz,
} from 'foo'

// Prettier 2.6
export {
foo,
bar as baz, // comment
};

import {
foo,
// comment
bar as baz,
} from "foo";

// Prettier 2.7
export {
foo,
// comment
bar as baz,
};

import {
foo,
// comment
bar as baz,
} from "foo";

TypeScript

// Input
[x as any] = x;

// Prettier 2.6
[x: any] = x;

// Prettier 2.7
[x as any] = x;

Fix formatting for typescript Enum with computed members (#12930 by @HosokawaR)

// Input
enum A {
[i++],
}

// Prettier 2.6
enum A {
i++,
}

// Prettier 2.7
enum A {
[i++],
}

Stop parsing invalid code (#12982 by @fisker)

// Input
const object = ({ methodName() });

// Prettier 2.6
const object = { methodName(); };

// Prettier 2.7
SyntaxError: Unexpected token. (1:29)
> 1 | const object = ({ methodName() });
| ^^

HTML

Support Speculation Rules API formatting in HTML (#12882 by @sosukesuzuki)

Please read https://web.dev/speculative-prerendering/ for more information about the Speculation Rules API.

<!-- Input -->
<script type="speculationrules">
{
"prerender": [
{"source": "list", "urls": ["https://a.test/foo"]}
]
}
</script>


<!-- Prettier 2.6 -->
<script type="speculationrules">
{
"prerender": [
{"source": "list", "urls": ["https://a.test/foo"]}
]
}
</script>

<!-- Prettier 2.7 -->
<script type="speculationrules">
{
"prerender": [{ "source": "list", "urls": ["https://a.test/foo"] }]
}
</script>

Vue

Allow formatting for Vue template expression written in TypeScript (#12584 by @sosukesuzuki)

<!-- input -->
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
{{ (x as number).toFixed(2) }}
</template>

<!-- Prettier 2.6 -->
<script setup lang="ts">
let x: string | number = 1
</script>

<template>
{{ (x as number).toFixed(2) }}
</template>

<!-- Prettier 2.7 -->
<script setup lang="ts">
let x: string | number = 1;
</script>

<template>
{{ (x as number).toFixed(2) }}
</template>

Infer Stylus parser for Vue SFC style block (#12707 by @lsdsjy)

<style lang="stylus"> blocks in Vue SFCs can be processed by the appropriate plugin if any.

Avoid printing attribute per line in Vue SFC blocks (#12895 by @sosukesuzuki)

<!-- Input (singleAttributePerLine: true) -->
<script lang="ts" setup>
</script>

<!-- Prettier 2.6 -->
<script
lang="ts"
setup
>
</script>

<!-- Prettier 2.7 -->
<script lang="ts" setup>
</script>

Angular

Fix shorthand properties formatting (#12993 by @sosukesuzuki, @fisker)

<!-- Input -->
<ng-container *ngTemplateOutlet="someTmpl; context: { app }"></ng-container>

<!-- Prettier 2.6 -->
<ng-container
*ngTemplateOutlet="someTmpl; context: { app: this.app }"
></ng-container>

<!-- Prettier 2.7 -->
<ng-container *ngTemplateOutlet="someTmpl; context: { app }"></ng-container>

GraphQL

Add support for printing SchemaExtension nodes (#12519 by @trevor-scheer)

# Input
extend schema { subscription: Subscription }
extend schema @directive

# Prettier 2.6
N/A - throws error

# Prettier 2.7
extend schema {
subscription: Subscription
}
extend schema @directive

Fix single line and empty description formatting (#12608 by @chimurai, @fisker)

# Input
""" Customer """
type Person {
name: String
}

""""""
type Person {
name: String
}

# Prettier 2.6.2
"""
Customer
"""
type Person {
name: String
}

"""

"""
type Person {
name: String
}

# Prettier 2.6.2 (second format)
"""
Customer
"""
type Person {
name: String
}

"""

"""
type Person {
name: String
}

# Prettier 2.7
"""
Customer
"""
type Person {
name: String
}

"""
"""
type Person {
name: String
}

CLI

# Prettier 2.6
$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] Code style issues found in the above file(s). Forgot to run Prettier?

# Prettier 2.7
$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] src/fileB.js
[warn] Code style issues found in 2 files. Forgot to run Prettier?

$ prettier src --check
Checking formatting...
[warn] src/fileA.js
[warn] Code style issues found in the above file. Forgot to run Prettier?

Infer parser for .importmap files (#12603 by @fisker)

Format .importmap files as JSON files.

Simplify performance test (#12682, #12698 by @fisker)

When --debug-benchmark or --debug-repeat is passed:

  1. The CLI skips print code to the screen or write file
  2. Set log level to debug automatically