[번역] 리액트 컴파일러

민순기·2024년 5월 17일
post-thumbnail

소개

이 문서에서는 React Compiler의 내용을 한국어로 번역하여 소개합니다.


이 페이지는 새로운 실험적인 React Compiler에 대한 소개와 이를 성공적으로 시도하는 방법을 제공합니다.

배우게 될 내용

  • 컴파일러 시작하기
  • 컴파일러와 eslint plugin 설치
  • 트러블슈팅

노트

React Compiler는 커뮤니티의 초기 피드백을 받기 위해 오픈 소스화된 새로운 실험적인 컴파일러입니다. 아직 다듬어야 할 부분이 많고, 완전히 프로덕션에 준비된 상태는 아닙니다.

React Compiler는 React 19 Beta가 필요합니다.

React Compiler는 커뮤니티의 초기 피드백을 받기 위해 오픈 소스화된 새로운 실험적인 컴파일러입니다. 이것은 React 앱을 자동으로 최적화하는 빌드 타임 전용 도구입니다.

이 도구는 일반 JavaScript와 함께 작동하며, React의 규칙을 이해하기 때문에 이를 사용하기 위해 코드를 다시 작성할 필요가 없습니다.

컴파일러는 컴파일러의 분석 결과를 바로 편집기에서 보여주는 eslint 플러그인도 포함합니다. 이 플러그인은 컴파일러와 독립적으로 실행되며, 앱에서 컴파일러를 사용하지 않더라도 사용할 수 있습니다.
모든 React 개발자가 코드베이스의 품질을 향상시키기 위해 이 eslint 플러그인을 사용하는 것을 권장합니다.

컴파일러가 하는 일?

컴파일러는 일반 JavaScript 의미와 React의 규칙을 이해하여 코드의 깊은 수준까지 이해합니다. 이를 통해 코드에 자동 최적화를 추가할 수 있습니다.

현재 useMemo, useCallback, 그리고 React.memo를 통한 수동 메모이제이션에 익숙할 수 있습니다. 컴파일러는 코드가 React의 규칙을 따를 경우 이를 자동으로 수행할 수 있습니다. 규칙 위반이 감지되면 해당 컴포넌트나 훅만 건너뛰고, 다른 코드는 안전하게 계속 컴파일합니다.

코드베이스가 이미 매우 잘 메모이제이션되어 있다면, 컴파일러로 큰 성능 개선을 기대하지 않을 수 있습니다. 그러나 실제로는 성능 문제를 일으키는 적절한 종속성을 손으로 정확하게 메모이제이션하는 것은 어려운 일입니다.

컴파일러를 사용해야 하나요?

컴파일러는 아직 실험적 단계에 있으며 많은 미완성 부분이 있음을 유의하세요. Meta와 같은 회사에서 프로덕션 환경에서 사용된 적은 있지만, 앱의 프로덕션에 컴파일러를 도입할지는 코드베이스의 상태와 React의 규칙을 얼마나 잘 따랐는지에 따라 달라집니다.

지금 당장 컴파일러를 사용하는 것을 서두를 필요는 없습니다. 안정적인 릴리스가 될 때까지 기다린 후 도입해도 괜찮습니다. 그러나 앱에서 소규모 실험으로 시도해 보고 피드백을 제공하여 컴파일러를 더 나아지게 하는 데 도움을 주시면 감사하겠습니다.

시작하기

이 문서 외에도, 컴파일러에 대한 추가 정보와 논의를 위해 React Compiler 저장소를 확인하는 것을 권장합니다.

컴파일러를 코드베이스에 도입하기

기존 프로젝트

컴파일러는 React의 규칙을 따르는 함수형 컴포넌트와 훅을 컴파일하도록 설계되었습니다. 규칙을 위반하는 코드도 처리할 수 있지만, 해당 컴포넌트나 훅을 건너뛰는 방식으로 처리합니다. 그러나 JavaScript의 유연한 특성 때문에 컴파일러가 모든 가능한 위반을 잡아내지 못할 수 있으며, 규칙을 위반한 컴포넌트나 훅을 실수로 컴파일하여 정의되지 않은 동작을 초래할 수 있습니다.

이 때문에, 기존 프로젝트에서 컴파일러를 성공적으로 도입하려면 먼저 제품 코드의 작은 디렉토리에서 실행해 보는 것을 권장합니다. 특정 디렉토리 세트에서만 컴파일러를 실행하도록 구성하여 이를 수행할 수 있습니다.

const ReactCompilerConfig = {
  sources: (filename) => {
    return filename.indexOf('src/path/to/dir') !== -1;
  },
};

드문 경우이지만, 컴파일러를 "opt-in" 모드로 실행하도록 구성할 수도 있습니다. 이를 위해 compilationMode: "annotation" 옵션을 사용합니다. 이 모드는 컴파일러가 "use memo" 지시어가 있는 컴포넌트와 훅만 컴파일하도록 합니다. 주의할 점은 주석 모드는 초기 도입자를 돕기 위한 임시적인 것이며, "use memo" 지시어를 장기적으로 사용할 계획은 없다는 것입니다.

const ReactCompilerConfig = {
  compilationMode: "annotation",
};

// src/app.jsx
export default function App() {
  "use memo";
  // ...
}

컴파일러 도입에 더 많은 확신이 생기면, 다른 디렉토리로 적용 범위를 확장하고 천천히 전체 앱으로 도입할 수 있습니다.

신규 프로젝트

새 프로젝트를 시작하는 경우, 기본적으로 전체 코드베이스에서 컴파일러를 활성화할 수 있습니다.

설치

호환성 확인

컴파일러를 설치하기 전에 먼저 코드베이스가 호환되는지 확인할 수 있습니다:

npx react-compiler-healthcheck

이 스크립트는 다음을 수행합니다:

  • 성공적으로 최적화할 수 있는 컴포넌트 수를 확인합니다: 숫자가 높을수록 좋습니다.
  • <StrictMode> 사용 여부를 확인합니다: 이를 활성화하고 따를 경우 React의 규칙을 따를 가능성이 높아집니다.
  • 호환되지 않는 라이브러리 사용 여부를 확인합니다: 컴파일러와 호환되지 않는 것으로 알려진 라이브러리를 검사합니다.

예시:

Successfully compiled 8 out of 9 components.
StrictMode usage not found.
Found no usage of incompatible libraries.

eslint-plugin-react-compiler 설치하기

React Compiler는 eslint 플러그인도 지원합니다. 이 eslint 플러그인은 컴파일러와 독립적으로 사용할 수 있으며, 컴파일러를 사용하지 않더라도 eslint 플러그인을 사용할 수 있습니다.

npm install eslint-plugin-react-compiler

이후에 eslint config에 아래 코드를 추가하세요:

module.exports = {
  plugins: [
    'eslint-plugin-react-compiler',
  ],
  rules: {
    'react-compiler/react-compiler': "error",
  },
}

Babel과 함께 사용하기

npm install babel-plugin-react-compiler

컴파일러에는 빌드 파이프라인에서 컴파일러를 실행하기 위해 사용할 수 있는 Babel 플러그인이 포함되어 있습니다.

설치 후, Babel 설정에 추가하십시오. 컴파일러가 파이프라인에서 먼저 실행되는 것이 중요합니다:

// babel.config.js
const ReactCompilerConfig = { /* ... */ };

module.exports = function () {
  return {
    plugins: [
      ['babel-plugin-react-compiler', ReactCompilerConfig], // must run first!
      // ...
    ],
  };
};

babel-plugin-react-compiler는 다른 Babel 플러그인보다 먼저 실행되어야 합니다. 컴파일러는 정확한 분석을 위해 입력 소스 정보를 필요로 하기 때문입니다.

Vite와 함께 사용하기

만약 Vite를 사용한다면, vite-plugin-react 플러그인을 추가할 수 있습니다.

// vite.config.js
const ReactCompilerConfig = { /* ... */ };

export default defineConfig(() => {
  return {
    plugins: [
      react({
        babel: {
          plugins: [
            ["babel-plugin-react-compiler", ReactCompilerConfig],
          ],
        },
      }),
    ],
    // ...
  };
});

Next.js와 함께 사용하기

Next.js는 Babel을 통해 더 느린 빌드 파이프라인을 허용하며, babel.config.js 파일을 추가하여 Babel을 구성하면 이를 활성화할 수 있습니다.

Remix와 함께 사용하기

vite-plugin-babel을 설치하고 컴파일러의 Babel 플러그인을 추가하세요:

npm install vite-plugin-babel
// vite.config.js
import babel from "vite-plugin-babel";

const ReactCompilerConfig = { /* ... */ };

export default defineConfig({
  plugins: [
    remix({ /* ... */}),
    babel({
      filter: /\.[jt]sx?$/,
      babelConfig: {
        presets: ["@babel/preset-typescript"], // if you use TypeScript
        plugins: [
          ["babel-plugin-react-compiler", ReactCompilerConfig],
        ],
      },
    }),
  ],
});

Webpack과 함께 사용하기

React Compiler를 위한 로더를 다음과 같이 직접 만들 수 있습니다:

const ReactCompilerConfig = { /* ... */ };
const BabelPluginReactCompiler = require('babel-plugin-react-compiler');

function reactCompilerLoader(sourceCode, sourceMap) {
  // ...
  const result = transformSync(sourceCode, {
    // ...
    plugins: [
      [BabelPluginReactCompiler, ReactCompilerConfig],
    ],
  // ...
  });

  if (result === null) {
    this.callback(
      Error(
        `Failed to transform "${options.filename}"`
      )
    );
    return;
  }

  this.callback(
    null,
    result.code
    result.map === null ? undefined : result.map
  );
}

module.exports = reactCompilerLoader;

Expo에서 사용하기

Expo는 Metro를 통해 Babel을 사용하므로 설치 지침은 Babel 사용 섹션을 참조하십시오.

React Native에서 사용하기 (Metro)

React Native는 Metro를 통해 Babel을 사용하므로 설치 지침은 Babel 사용 섹션을 참조하십시오.

트러블 슈팅

이슈 리포팅

이슈를 리포팅하려면 먼저 React Compiler Playground에서 최소 재현 예제를 만들어 버그 보고서에 포함하십시오.

facebook/react 리포지토리에서 문제를 열 수 있습니다.

React Compiler 작업 그룹에 가입하여 피드백을 제공할 수도 있습니다. 가입에 대한 자세한 내용은 README를 참조하십시오.

일반적인 문제

(0 , _c) is not a function 오류
이 오류는 React 19 Beta 이상을 사용하지 않을 때 JavaScript 모듈 평가 중에 발생합니다. 이를 해결하려면 먼저 앱을 React 19 Beta로 업그레이드하십시오.

디버깅

컴포넌트가 최적화되었는지 확인하기

React DevTools
React Devtools(v5.0+)는 React Compiler를 지원하며, 컴파일러에 의해 최적화된 컴포넌트 옆에 “Memo ✨” 배지를 표시합니다.

기타 문제

https://github.com/reactwg/react-compiler/discussions/7를 참조하십시오.

profile
2년차 FE 개발자 민순기입니다.

0개의 댓글