Prettier v3 변경사항 살펴보기

1ilsang
1ilsang
클라이밍 하실래염?
published

cover

Prettier v3.0이 어제 7월 5일에 공개되었다.

내용은 읽으면서 흥미로웠던 부분들 위주로 주요 변경점들을 기준으로 간략하게 소개 하려고 한다.

Prettier 플러그인 개발쪽의 변경사항도 크지만 실제 사용성 위주로 정리를 했다.

TL;DR!

  1. trailingComma 옵션이 all으로 변경되었다.
  2. 주석 및 MD 문서의 린팅 편의성이 높아졌다(한국어 린트가 향상되었다)
  3. 최소 요구 Node 버전이 14가 되었다.
  4. .gitignore가 드디어 기본적으로 무시된다(.prettierignore는 유지).
  5. 화살표 함수/타입의 린트가 코드 패턴을 지원.

Markdown

한국어 처리의 향상

<!-- 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 -->

노래를 못해요.

한국어는 공백의 위치에 따라 문장의 의미가 변경되는 특성이 있다.

  • 노래를 못해요: 나는 노래를 잘 못한다.
  • 노래를 못 해요: 나는 (어떠한 이유로) 노래를 할 수 없다.

v3에서는 위의 특성을 고려해 단어를 '분해하지' 않는다. 영어와 동일하게 줄바꿈이 일어나게 된다.

인라인 코드 여백 유지

<!-- Input -->

`   foo   bar   baz   `

<!-- Prettier 2.8 -->

`foo bar baz`

<!-- Prettier 3.0 -->

`   foo   bar   baz   `

다수의 여백이 하나로 줄여지던 문제가 해결되었다.

JavaScript / TypeScript

trailing-comma

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

타입 매개변수 및 튜플에서도 쉼표가 추가되었다.

Decorated function 패턴 지원

// 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;
}) => {
  // ...
});

데코레이터 패턴에서 들여쓰기를 줄이기 위해 화살표 함수의 가독성을 희생하도록 변경되었다.

누락된 await 괄호 추가

// 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
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));

Import Attributes를 지원

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

주석이 있는 경우 유니온 타입의 개행이 유지

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

extends 줄바꿈 개선

// 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 };

HTML

SVG 내부 script 린트 향상

<!-- 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>

Reference