1. 배경 및 변환 전략

최정우·2022년 4월 28일
0

1. 배경 설명

내 지난 포스팅 React-Storybook 0. 프로젝트 생성 및 스토리북 등록 에서 나는 앞으로 내가 만들게 될 리액트 컴포넌트 들을 최대한 재사용성을 높여서 등록하고, 그것들을 모아두겠다고 말했었다. 그렇게 CRA를 이용하여 프로젝트를 만들어 봤었다.

그런데 여기서 미쳐 생각하지 못했던 문제가 생겼다. 바로 CRA를 할때 TS, 즉 타입스크립트를 이용하도록 생성하지 않았던 것이다.

그렇게 우선, 예시로 주어진 컴포넌트의 확장자를 .jsx 에서 .tsx 로 바꾸어 보았지만 역시 어림도 없었나보다.빨간줄의 에러를 상당히 많이 볼 수 있었다.

물론 그 당시에는 프로젝트를 생성한지 얼마 안되었기 때문에, 사실 프로젝트를 지우고 다시 TS 프로젝트로 만들면 됐다. 하지만 만약 이미 JS로 프로젝트를 만들었는데 그 이후 타입스크립트를 도입하고 싶을 떄, 할 수 있어야 하기에 방법을 찾아 한번 직접 바꿔보려고 한다.

2. 영문 포스팅 글 번역

원본 링크 : https://medium.com/opensanca/migrating-from-js-to-ts-cra-b5f679086c5a

참고 링크 : https://create-react-app.dev/docs/adding-typescript/

Javascript를 Typescript로 바꾸기(CRA)

자바스크립트로 짜여진 CRA 프로젝트를 타입스크립트로 바꾸는 방법에 대해서 설명하겠다.

**CRA 공식 문서** 를 참고 해도 되지만, 이 글을 읽으면 더 깊은 학습을 할 수 있을 것을 약속한다.

당신의 타입스크립트로의 모든 코드베이스를 바꾸는 훌륭한 전략을 소개할 것인데,

그것을 위해 3가지 스텝으로 분류했다.

  1. 어떻게 스스로 타입스크립트를 구성하고, linter/prettier 등을 고치고 jest를 통합시킬 것인가?
  2. 간단한 리팩토링을 통해 최대한 머리아프지 않게 현재 당신의 코드를 타입스크립트로 바꾸는 전략
  3. 내가 지금까지 공부했고, 나를 도왔고, 내가 범했던 다양한 실수들 그리고 거기서 나의 문제를 해결해줬던 config들 소개

Configs(구성)

첫째, 어플리케이션 작동에 문제가 없게 하는데 초점을 맞출 것이다.

둘째, 코딩 생활을 더 쉽게 만들어주는 linter랑 prettier를 고칠 것이다.

셋째, JS와 TS에서 모두 작동하는 테스트 코드를 구성할 것이다.

App

이 설정은 가장 쉽다. CRA 구성은 JS,TS를 동시에 모두 지원하기에 너는 단지 타입스크립트 컴파일러를 구성하면 된다. 여기서 생각해봐야할 점은, 이전에 구성한 적 없는 tsconfig.json 파일을 어디서 가져오는 지에 대한 것이다.

그래서 타입스크립트 템플릿으로 CRA를 사용하여 새로운 프로젝트를 만든 후 생성되는 tsconfig.json을 이용하고 몇 가지 설정을 추가할 것이다. (ex baseUrl (NODE_PATH 바꾸기 위함)).

타입스크립트 CRA 프로젝트를 너의 어플에 적용하기 위해서는 TS Dependencies를 설치하고 너의 app's roottsconfig.json 을 추가해라.

yarn add typescript @types/react @types/react-dom @types/node
//tsconfig.json
{
  "compilerOptions": {
    "baseUrl": "src/",
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "esModuleInterop": true
  },
  "include": [
    "src"
  ],
  "exclude": [
    "**/*.test.ts",
    "**/*.test.tsx"
  ]
}

Linter/Prettier

linter와 prettier 에 대해 말하자면 입아프자. 나는 타입스크립트에서 작동하도록 내 eslint 설정을 업데이트 했다. 만약 아직 linter나 prettier를 사용하지 않는다면, 아무리 작은 사이드 프로젝트라 할 지 라도 당장 너가 하던 것을 멈추고 추가할 것을 권한다.

아래의 dependencies를 eslint나 prettier 에 추가하고, .eslintrc.js (.ts 파일 확장자를 인식하기 위한 파일) 을 업데이트하고 타입스크립트 플러그인을 사용해라.

yarn @typescript-eslint/eslint-plugin @typescript-eslint/parser
// .eslintrc.js
module.exports = {
  plugins: ['prettier', 'react', '@typescript-eslint'],
  extends: [
    './node_modules/kcd-scripts/eslint.js',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
    'prettier/@typescript-eslint',
  ],
  rules: {
    'prettier/prettier': 'error',
    'react/jsx-filename-extension': [
      1,
      { extensions: ['.js', '.jsx', '.tsx'] },
    ],
  },
  settings: {
    'import/resolver': {
      node: {
        extensions: ['.js', '.jsx', '.ts', '.tsx'],
        paths: ['src'],
      },
    },
  },
}
//prettier.config.js
const prettierConfig = require('kcd-scripts/prettier');

module.exports = Object.assign(prettierConfig, {
  bracketSpacing: true,
  endOfLine: 'lf',
});

Tests

너의 모든 테스트와 컴포넌트들은 JS로 작성되어 있다. jest는 컴포넌트가 JS로 작성되었든 TS로 작성되었든 신경쓰지 않고 적용된다. 아무것도 할 필요가 없다.

그런데 TS 컴포넌트를 추가하고 나면, TS 테스트 코드를 작성하고 싶을 수 있다. 이 경우에는 TS로 작성된 테스트를 변환하도록 jest.config.js 를 손봐야 합니다. jest에 dependencies를 추가하고 업데이트 해라.

yarn add ts-jest @types/jest
//jest.config.js
const { jest: jestConfig } = require('kcd-scripts/config')

module.exports = Object.assign(jestConfig, {
  globalSetup: '<rootDir>/src/setupJest',
  modulePaths: ['<rootDir>/src/'],

  transform: {
    ...jestConfig.transform,
    '\\.tsx?$': 'ts-jest',
    '^.+\\.jsx?$': 'babel-jest',
  },

  globals: {
    'ts-jest': {
      tsConfig: 'tsconfig.json',
    },
  },
})

변환 전략

TS와 JS 둘다 작동가능하게 하는 하이브리드 앱을 구성하는 것은 쉽다. 전체 어플리케이션을 바꾸는 것은 엄천난 도전이 될 것이다. 나는 내 어플리케이션을 변환하는데 도움을 준 4가지 전략을 소개한다.

첫째, 작은 것(leaves) 부터 변환을 시작해라.

너의 어플리케이션은 마치 나무처럼 동작 할 것이다 .나무 처럼 동작한다면 가능한 다른 내부적인 의존성이 없는 마지막 컴포넌트 부터 재작성 하기 시작해라. 그렇게 하면 충돌이 적어질 것이고 모든 leaf가 변환이 되었다면 그 모든 부모 컴포넌트 들을 변환해서 루트까지 변환해 가라.

둘째, 너의 테스트 코드 부터 재작성해라.
너의 코드 베이스의 각각의 테스트 코드 확장자를 .js 에서 .ts로 바꾸고 생기는 문제들을 먼저 고쳐라. 그렇게 고쳐진 테스트 코드들은 타입스크립트로 재작성 될 너의 코드들의 수많은 비준수 사항, 오류 등을 잡아 낼 수 있을 것이다.

셋째, 새로운 기능부터 시작해라.

오직 새로운 기능만을 TS로 작성하면 새로운 기능을 테스트하기 위한 새로운 코드와 새로운 루틴을 작성하면 사용이 더 쉬워진다. 새로운 기능은 당신이 예측하기 쉽고, 컨트롤 가능한 영역의 영향을 노출한다.

넷째, 필요할 때 마다 변환해라.

사실 이 것은 가장 어려울 수 있지만 가장 현실적이다. 손 볼 필요가 있는 특정한 파일이 있다면 그 파일만 우선적으로 변환해라. 만약 너가 그 파일에 대한 테스트 코드가 있다면( 사실 이것이 반드시 있기를 바란다.), 그 테스트 코드를 먼저 수정하고 그 후에 너의 컴포넌트를 변환하기를 추천한다. 그렇게 새로운 제품 요청사항이나 디자인 변화 등의 변경사항에 너의 컴포넌트를 수정 해나가라.

profile
누구나 할 수 있지만 아무나 못하는 일을 하자

0개의 댓글