compilationMode – React

compilationMode 옵션은 React 컴파일러가 어떤 함수를 컴파일할지 선택하는 방식을 제어합니다.

{

compilationMode: 'infer' // or 'annotation', 'syntax', 'all'

}


레퍼런스

compilationMode

React 컴파일러가 최적화할 함수를 결정하는 전략을 제어합니다.

타입

'infer' | 'syntax' | 'annotation' | 'all'

기본값

'infer'

옵션

  • 'infer' (기본값): 컴파일러가 지능형 휴리스틱을 사용하여 React 컴포넌트와 Hook을 식별합니다.

    • "use memo" 지시어로 명시적으로 표시된 함수.
    • 컴포넌트(PascalCase) 또는 Hook(use 접두사)처럼 이름이 지어진 함수이면서 JSX를 생성하거나 다른 Hook을 호출하는 함수.
  • 'annotation': "use memo" 지시어로 명시적으로 표시된 함수만 컴파일합니다. 점진적 도입에 이상적입니다.

  • 'syntax': Flow의 ComponentHook 문법을 사용하는 컴포넌트와 Hook만 컴파일합니다.

  • 'all': 모든 최상위 함수를 컴파일합니다. React가 아닌 함수도 컴파일할 수 있으므로 권장하지 않습니다.

주의 사항

  • 'infer' 모드는 함수가 React 명명 규칙을 따라야 감지할 수 있습니다.
  • 'all' 모드를 사용하면 유틸리티 함수까지 컴파일하여 성능에 부정적인 영향을 미칠 수 있습니다.
  • 'syntax' 모드는 Flow가 필요하며 TypeScript와는 작동하지 않습니다.
  • 모드와 관계없이 "use no memo" 지시어가 있는 함수는 항상 건너뜁니다.

사용법

기본 추론 모드

기본 'infer' 모드는 React의 규칙을 따르는 대부분의 코드베이스에서 잘 작동합니다.

{

compilationMode: 'infer'

}

이 모드에서는 다음 함수들이 컴파일됩니다.

// ✅ 컴파일됨: 컴포넌트처럼 이름이 지어졌고 JSX를 반환함

function Button(props) {

return <button>{props.label}</button>;

}

// ✅ 컴파일됨: Hook처럼 이름이 지어졌고 Hook을 호출함

function useCounter() {

const [count, setCount] = useState(0);

return [count, setCount];

}

// ✅ 컴파일됨: 명시적인 지시어

function expensiveCalculation(data) {

"use memo";

return data.reduce(/* ... */);

}

// ❌ 컴파일되지 않음: 컴포넌트/Hook 패턴이 아님

function calculateTotal(items) {

return items.reduce((a, b) => a + b, 0);

}

어노테이션 모드를 사용한 점진적 도입

점진적 마이그레이션을 위해 'annotation' 모드를 사용하여 표시된 함수만 컴파일합니다.

{

compilationMode: 'annotation'

}

그런 다음 컴파일할 함수를 명시적으로 표시합니다.

// 이 함수만 컴파일됩니다

function ExpensiveList(props) {

"use memo";

return (

<ul>

{props.items.map(item => (

<li key={item.id}>{item.name}</li>

))}

</ul>

);

}

// 지시어가 없으면 컴파일되지 않습니다

function NormalComponent(props) {

return <div>{props.content}</div>;

}

Flow 문법 모드 사용하기

코드베이스가 TypeScript 대신 Flow를 사용하는 경우입니다.

{

compilationMode: 'syntax'

}

그런 다음 Flow의 컴포넌트 문법을 사용합니다.

// 컴파일됨: Flow 컴포넌트 문법

component Button(label: string) {

return <button>{label}</button>;

}

// 컴파일됨: Flow Hook 문법

hook useCounter(initial: number) {

const [count, setCount] = useState(initial);

return [count, setCount];

}

// 컴파일되지 않음: 일반 함수 문법

function helper(data) {

return process(data);

}

특정 함수 제외하기

컴파일 모드와 관계없이 "use no memo"를 사용하여 컴파일을 건너뛸 수 있습니다.

function ComponentWithSideEffects() {

"use no memo"; // 컴파일 방지

// 이 컴포넌트는 메모이제이션되어서는 안 되는 사이드 이펙트가 있습니다

logToAnalytics('component_rendered');

return <div>Content</div>;

}


문제 해결

'infer' 모드에서 컴포넌트가 컴파일되지 않는 경우

'infer' 모드에서는 컴포넌트가 React의 규칙을 따르는지 확인하세요.

// ❌ 컴파일되지 않음: 소문자 이름

function button(props) {

return <button>{props.label}</button>;

}

// ✅ 컴파일됨: PascalCase 이름

function Button(props) {

return <button>{props.label}</button>;

}

// ❌ 컴파일되지 않음: JSX를 생성하거나 Hook을 호출하지 않음

function useData() {

return window.localStorage.getItem('data');

}

// ✅ 컴파일됨: Hook을 호출함

function useData() {

const [data] = useState(() => window.localStorage.getItem('data'));

return data;

}