Showing posts with label react. Show all posts
Showing posts with label react. Show all posts

Tuesday, July 31, 2018

리액트 타입스크립트 프로젝트, 시작부터 제대로 설정하기

create-react-app(CRA)은 리액트 애플리케이션 개발을 시작하는 가장 빠르고 편리한 방법 중 하나입니다. 특히 타입스크립트 템플릿(--template typescript)을 사용하면 복잡한 초기 설정 없이도 바로 타입-세이프한 개발 환경을 구축할 수 있습니다. 하지만 CRA가 제공하는 기본 설정은 '만인을 위한' 범용적인 구성입니다. 이는 곧, 실제 프로덕션 레벨의 프로젝트나 특정 팀의 요구사항에 맞추기 위해서는 몇 가지 추가적인 개선 작업이 필요하다는 의미이기도 합니다.

기본 설정은 깔끔해 보이지만, 실제 개발에 들어가면 불필요한 파일들이 존재하고, 타입스크립트 설정은 더 엄격하게 가져갈 수 있으며, 코드 스타일을 일관성 있게 유지하기 위한 도구들의 연동이 아쉽습니다. 이 글에서는 CRA로 생성한 리액트 타입스크립트 프로젝트의 초기 설정을 어떻게 더 효율적이고 전문적으로 개선할 수 있는지 단계별로 상세히 알아보겠습니다.

1. 프로젝트 초기 구조 정리하기: 불필요한 파일 제거

CRA로 프로젝트를 생성하면 src 폴더 안에 여러 기본 파일들이 포함됩니다. 이는 리액트의 작동 방식을 보여주기 위한 예제 파일들이지만, 실제 프로젝트를 시작할 때는 대부분 필요하지 않습니다.

새 프로젝트의 초기 파일 구조는 다음과 같습니다:

/src
├── App.css
├── App.tsx
├── App.test.tsx
├── index.css
├── index.tsx
├── logo.svg
├── react-app-env.d.ts
├── reportWebVitals.ts
└── setupTests.ts

여기서 과감하게 정리할 수 있는 파일들은 다음과 같습니다.

  • logo.svg: 리액트 로고 SVG 파일입니다. 프로젝트의 로고나 이미지를 사용할 것이므로 제거합니다.
  • App.test.tsx: App 컴포넌트에 대한 기본 테스트 파일입니다. Jest와 React Testing Library를 사용한 예제이지만, 실제 테스트 코드는 직접 작성해야 하므로 초기 파일은 삭제해도 무방합니다.
  • setupTests.ts: 테스트 환경을 설정하는 파일입니다. 나중에 필요에 따라 다시 구성할 수 있습니다.
  • reportWebVitals.ts: 웹 바이탈(성능 지표)을 측정하는 유틸리티 함수입니다. 초기 개발 단계에서는 필수가 아니며, 필요시 언제든지 다시 추가할 수 있습니다.
  • App.css: App.tsx에 대한 기본 스타일 파일입니다. 보통 CSS-in-JS(Styled-components, Emotion)나 Tailwind CSS 같은 다른 스타일링 솔루션을 도입하므로 제거합니다.

위 파일들을 삭제하고 나면 src 폴더는 훨씬 간결해집니다.

/src
├── App.tsx
├── index.css
├── index.tsx
└── react-app-env.d.ts

이제 파일 삭제에 따른 코드 수정이 필요합니다.

먼저 index.tsx에서 reportWebVitals 관련 코드를 제거합니다.

// src/index.tsx

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
// import reportWebVitals from './reportWebVitals'; // 이 줄을 삭제합니다.

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// reportWebVitals(); // 이 줄도 삭제합니다.

다음으로 App.tsx에서 로고 import와 기본 마크업을 정리합니다.

// src/App.tsx

import React from 'react';
// import logo from './logo.svg'; // 로고 import 삭제
// import './App.css'; // CSS import 삭제

function App() {
  return (
    <div>
      <h1>My React App</h1>
      <p>프로젝트 설정이 완료되었습니다.</p>
    </div>
  );
}

export default App;

이렇게 초기 구조를 정리하면, 꼭 필요한 파일들만 남게 되어 프로젝트의 본질에 더 집중할 수 있습니다.

2. `tsconfig.json` 강화하기: 더 엄격하고 편리한 타입 환경

tsconfig.json 파일은 타입스크립트 컴파일러의 동작을 제어하는 핵심 설정 파일입니다. CRA의 기본 설정도 훌륭하지만, 몇 가지 옵션을 추가하여 코드의 안정성을 높이고 개발 편의성을 개선할 수 있습니다.

절대 경로(Absolute Imports) 설정

프로젝트 규모가 커지면 컴포넌트 간의 상대 경로 참조(../../components/Button)가 매우 복잡해집니다. 이를 해결하기 위해 baseUrl 옵션을 설정하여 절대 경로를 사용할 수 있습니다.

tsconfig.json 파일의 compilerOptions에 다음을 추가합니다.

{
  "compilerOptions": {
    "baseUrl": "src",
    // ... 기존 옵션들
  },
  "include": ["src"]
}

이제 src 디렉토리를 기준으로 절대 경로를 사용할 수 있습니다.

  • 변경 전: import Button from '../../components/common/Button';
  • 변경 후: import Button from 'components/common/Button';

파일을 다른 위치로 이동시켜도 import 경로를 수정할 필요가 없어 유지보수성이 크게 향상됩니다.

더 엄격한 컴파일러 옵션 추가

코드의 잠재적인 오류를 컴파일 시점에 미리 발견하기 위해 몇 가지 유용한 옵션을 활성화하는 것이 좋습니다.

  • "noUnusedLocals": true: 사용되지 않는 지역 변수가 있으면 에러를 발생시킵니다. 코드를 깔끔하게 유지하는 데 도움이 됩니다.
  • "noUnusedParameters": true: 사용되지 않는 함수 파라미터가 있으면 에러를 발생시킵니다. 인터페이스 구현 등 불가피한 경우, 파라미터 이름 앞에 언더스코어(_)를 붙여(예: _unusedParam) 의도적으로 무시할 수 있습니다.
  • "forceConsistentCasingInFileNames": true: 파일 이름의 대소문자를 일관되게 사용하도록 강제합니다. macOS와 같이 대소문자를 구분하지 않는 파일 시스템과 Linux 기반의 배포 환경(대소문자 구분) 간의 잠재적인 문제를 방지합니다.

이 옵션들을 추가한 compilerOptions 예시는 다음과 같습니다.

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true, // 추가
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    // 추가된 옵션들
    "baseUrl": "src",
    "noUnusedLocals": true,
    "noUnusedParameters": true
  },
  "include": ["src"]
}

3. 코드 품질 관리 자동화: ESLint와 Prettier 연동

일관된 코드 스타일과 잠재적인 버그 예방은 협업 프로젝트의 필수 요소입니다. CRA는 기본적으로 ESLint를 내장하고 있지만, 코드 포맷팅 도구인 Prettier와 함께 사용하면 시너지를 극대화할 수 있습니다.

  • ESLint: 코드의 문법적 오류나 안티 패턴 등 '논리적'인 문제를 찾아내는 린터(Linter)입니다.
  • Prettier: 코드의 스타일(들여쓰기, 줄 바꿈, 따옴표 등)을 정해진 규칙에 따라 자동으로 맞춰주는 포맷터(Formatter)입니다.

이 둘을 연동하면 ESLint는 코드 품질에 집중하고, Prettier는 코드 스타일에 집중하여 각자의 역할을 명확히 할 수 있습니다.

설치 및 설정

먼저 Prettier와 ESLint 연동을 위한 패키지를 설치합니다.

# npm 사용 시
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier

# yarn 사용 시
yarn add -D prettier eslint-config-prettier eslint-plugin-prettier
  • prettier: Prettier 코어 라이브러리
  • eslint-config-prettier: ESLint의 포맷팅 관련 규칙 중 Prettier와 충돌하는 것들을 비활성화합니다.
  • eslint-plugin-prettier: Prettier의 규칙을 ESLint 규칙으로 가져와서 실행합니다. 포맷팅이 잘못된 부분을 ESLint 에러로 표시해줍니다.

설정 파일 생성 및 수정

1. Prettier 설정 파일 (`.prettierrc`)

프로젝트 루트에 .prettierrc 파일을 생성하고 원하는 포맷팅 규칙을 정의합니다. JSON이나 JS 형식으로 작성할 수 있습니다.

{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "all",
  "printWidth": 80,
  "arrowParens": "always"
}
  • semi: 문장 끝에 세미콜론을 붙입니다.
  • singleQuote: 문자열에 홑따옴표를 사용합니다.
  • tabWidth: 들여쓰기 칸 수를 2로 설정합니다.
  • trailingComma: 객체나 배열의 마지막 요소 뒤에 쉼표를 붙입니다.
  • printWidth: 한 줄의 최대 길이를 80자로 제한합니다.
  • arrowParens: 화살표 함수의 파라미터가 하나일 때도 괄호를 사용합니다. (예: (x) => x)

2. ESLint 설정 파일 (`package.json` 또는 `.eslintrc.js`)

CRA는 기본적으로 package.json 파일 안에 eslintConfig 필드를 사용합니다. 이 부분을 수정하여 Prettier와의 연동을 설정합니다. extends 배열의 가장 마지막에 "plugin:prettier/recommended"를 추가하는 것이 중요합니다. 이 설정이 다른 규칙들을 덮어쓰면서 충돌을 방지하기 때문입니다.

// package.json
"eslintConfig": {
  "extends": [
    "react-app",
    "react-app/jest",
    "plugin:prettier/recommended" // 이 부분을 추가합니다.
  ]
},

이제 VSCode와 같은 에디터에서 "Format On Save" 옵션을 활성화하면 파일을 저장할 때마다 Prettier가 자동으로 코드를 정리해주고, ESLint는 코드 품질 문제를 알려주게 됩니다.

더 나아가, react-redux-typescript-guide와 같은 잘 정리된 가이드를 참고하면, 리덕스(Redux)를 포함한 복잡한 상태 관리 환경에서의 타입스크립트 및 ESLint 설정에 대한 깊이 있는 인사이트를 얻을 수 있습니다.

4. 패키지 매니저 선택: npm vs. Yarn

대부분의 자바스크립트 튜토리얼이나 문서가 npm을 기준으로 설명하지만, Yarn은 여전히 많은 개발자들에게 사랑받는 훌륭한 대안입니다. 특히 초기 Yarn은 npm의 단점이었던 속도와 의존성 관리의 일관성 문제를 해결하며 큰 인기를 얻었습니다.

물론 현재의 npm(버전 7 이상)은 많이 개선되어 Yarn과의 격차를 크게 줄였지만, Yarn은 여전히 다음과 같은 장점을 가집니다.

  • 속도: 강력한 캐싱 메커니즘 덕분에 한번 설치한 패키지는 다음부터 매우 빠르게 설치됩니다.
  • 안정적인 의존성 관리: yarn.lock 파일은 모든 개발 환경에서 동일한 버전의 패키지를 설치하도록 보장하여 "내 컴퓨터에서는 됐는데..."와 같은 문제를 최소화합니다.
  • Workspaces: 하나의 저장소에서 여러 패키지를 관리하는 모노레포(Monorepo) 구성을 네이티브로 강력하게 지원합니다.

CRA 프로젝트에서 npm 대신 Yarn을 사용하는 것은 매우 간단합니다. 프로젝트 생성 시 Yarn이 설치되어 있다면 CRA가 자동으로 Yarn을 사용합니다. 만약 npm으로 생성된 프로젝트를 Yarn으로 전환하고 싶다면, 다음 단계를 따르세요.

  1. 프로젝트 루트에서 package-lock.json 파일을 삭제합니다.
  2. 터미널에서 yarn install (또는 간단히 yarn) 명령을 실행합니다.

이것만으로 yarn.lock 파일이 생성되고, 이후부터는 yarn 명령어를 통해 패키지를 관리할 수 있습니다. (예: yarn add <package-name>, yarn remove <package-name>)

npm에서 Yarn으로의 마이그레이션에 대한 더 자세한 정보는 Yarn 공식 마이그레이션 가이드에서 확인할 수 있습니다.

결론: 견고한 시작이 성공적인 프로젝트를 만든다

지금까지 Create React App으로 생성한 타입스크립트 프로젝트의 초기 설정을 개선하는 네 가지 방법을 살펴보았습니다.

  1. 불필요한 파일 정리로 프로젝트 구조를 간결하게 만들고,
  2. tsconfig.json 강화를 통해 타입 안정성과 개발 편의성을 높였으며,
  3. ESLint와 Prettier 연동으로 코드 품질과 스타일을 자동으로 관리하고,
  4. Yarn과 같은 패키지 매니저를 의식적으로 선택하여 개발 환경의 일관성과 속도를 개선했습니다.

이러한 초기 설정 과정은 다소 번거롭게 느껴질 수 있지만, 장기적인 관점에서 보면 매우 가치 있는 투자입니다. 잘 정돈된 프로젝트는 새로운 팀원이 합류했을 때 적응 시간을 단축시키고, 잠재적인 버그를 사전에 방지하며, 무엇보다 개발 과정 자체를 훨씬 즐겁고 생산적으로 만들어줍니다. 여기서 소개한 설정들을 기반으로 자신만의, 혹은 팀만의 프로젝트 템플릿을 만들어보는 것도 좋은 다음 단계가 될 것입니다.

Friday, July 27, 2018

리액트(react) / 리액트 네이티브(react-native) 타입스크립트 설정 쉽게 적용해서 프로젝트 생성하기!

리액트(React)와 리액트 네이티브(React Native)에서 타입스크립트 설정을 쉽게 적용하여 프로젝트 생성하기

프로젝트를 시작할 때 설정을 잡는 일은 귀찮고 힘든 일일 수 있습니다. 하지만 리액트에서는 'create-react-app'과 'create-react-native-app' 같은 도구를 제공하여 이런 불편함을 해결하고 있습니다.

리액트와 리액트 네이티브의 타입스크립트 설정 방법

아래의 명령어를 사용하면, 타입스크립트 설정이 완료된 상태에서 바로 프로젝트를 생성할 수 있습니다.

- 리액트:
create-react-app <앱이름> --scripts-version=react-scripts-ts

- 리액트 네이티브:
create-react-native-app <앱이름> --scripts-version=react-native-scripts-ts

추가 정보

'create-react-native-app (CRNA)'에 관한 좋은 글도 발견해서 공유합니다:

https://jongmin92.github.io/2017/07/20/ReactNative/create-react-native-app/#6