Skip to main content

realworld를 이용하여 react app 만들기 - Step1: Installation

· 6 min read

realworld와 다음과 같은 기술 스텍을 이용해 react app을 만들고, 해당 서비스를 배포해가는 과정을 기록하기 위한 글이다.

  • yarn2
  • TypeScript v4.3.x
  • react-scripts v4.x.x
  • React v17.x.x
  • React Router v 6.x
  • emotion v11.4.x
  • Storybook v6.3.x
  • @testing-library/react v12.x.x

Create React App

create-react-app을 이용해서 기본적인 react app을 생성한다. TypeScript를 사용하기 위해 --template typescript 옵션을 추가해주었다.

npx create-react-app my-app --template typescript

Configure yarn2

yarn2를 패키지 매니저로 사용하기 위해 해당 프로젝트에 설정을 해주었다.

Configure ESLint, Prettier

eslint와 prettier 설정을 위해 아래와 같은 패키지를 설치한다.

npm install -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-prettier prettier

아래의 패키지들은 각자 프로젝트에 정의하는 규칙에 따라 달라질 수 있다.

npm install -D eslint-config-react eslint-import-resolver-babel-module eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks

package.json에 lint를 실행하기 위한 스크립트를 다음과 같이 추가한다.

// package.json
"prelint": "tsc --noEmit",
"lint": "eslint --ext=jsx,ts,tsx src",

Configure lint-staged, husky

git stage에 올라간 파일에 대해 git hook을 이용해 lint를 수행하기 위해 lint-stagedhusky를 설치한다

  1. 패키지를 설치한다.
npm install husky lint-staged --dev
  1. .lintstagedrc.js 파일을 생성하고 https://gist.github.com/gloriaJun/fd5dd389cf727faba1ad66a3cb7427ee#file-lintstagedrc-js 와 같이 정의한다.
  2. husky hook을 생성한다.
npx husky install
  1. commit 이전에 lint를 수행하기 위해 .husky/pre-commit 파일을 다음과 같이 정의한다.
npx husky add .husky/pre-commit "yarn lint-staged"

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn lint-staged

Configure commitlint

commitlint는 git hook을 이용하여 commit 메시지에 대한 커밋 메시지 스타일 체크를 위한 패키지이다.

  1. 패키지를 설치한다.
npm install -D @commitlint/cli @commitlint/config-conventional
  1. .commitlintrc.js 파일을 생성하고 https://gist.github.com/gloriaJun/fd5dd389cf727faba1ad66a3cb7427ee#file-commitlintrc-js와 같이 정의한다.
  2. .husky/commit-msg 파일을 생성하고 아래와 같이 정의한다.
npx commitlint --edit $1

Configure storybook

  1. storybook을 설치한다.
npx sb init
  1. package.json의 아래와 같이 eslintConfig 항목에 정의된 부분을 .eslintrc.js 설정 파일로 옮겨서 정의해준다.
 "eslintConfig": {
"overrides": [
{
"files": [
"**/*.stories.*"
],
"rules": {
"import/no-anonymous-default-export": "off"
}
}
]
},

스토리북이 정상적으로 설치가 완료되고, 아래와 같이 실행하여 스토리북 서비스가 기동이 잘 되는 지 확인해볼 수 있다.

# Starts Storybook in development mode
npm run storybook

해당 과정까지 문제없이 수행이 되었다면, react-app 생성은 완료된 것이다.

Trouble Shooting

husky - Hooks not running

아래와 같은 메시지를 보여주며 husky가 동작을 하지 않는다면.... 정의한 hook 파일의 파일 권한에 chmod +x .husky/<hookname>을 수행하여 실행 권한을 추가해주어야 한다.

╰─❯ git ci -m "chore: add husky"
힌트: '.husky/pre-commit' 후크가 실행 가능하도록 설정되지 않아서, 무시됩니다.
힌트: 이 경고는 `git config advice.ignoredHook false` 명령으로 끌 수 있습니다.
[master af6b6e3] chore: add husky
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 .husky/pre-commit

ERROR in ./.yarn/$$virtual/@pmmmwh-react-refresh-webpack-plugin-virtual...

스토리북 실행 중에 아래와 같은 오류가 발생하면..

ERROR in Failed to load config "react-app" to extend from.
Referenced from: /Users/user/Documents/mio/my-app/package.json

ERROR in ./.yarn/$$virtual/@pmmmwh-react-refresh-webpack-plugin-virtual-5ef0209fe8/0/cache/@pmmmwh-react-refresh-webpack-plugin-npm-0.4.3-5375cf6b6f-718853bf7b.zip/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource.js
Module not found: Error: @pmmmwh/react-refresh-webpack-plugin tried to access webpack-hot-middleware (a peer dependency) but it isn't provided by its ancestors; this makes the require call ambiguous and unsound.

Required package: webpack-hot-middleware (via "webpack-hot-middleware/client")
Required by: @pmmmwh/react-refresh-webpack-plugin@virtual:aa8e2a7880c7d78a363a64638c8d08e1ed334a2ec81820e6145b829d0a51f0466091afc671f5cadd8190c27d433059941023876a9c0e48dc23dca7c6014ea052#npm:0.4.3 (via /Users/user/Documents/mio/my-app/.yarn/$$virtual/@pmmmwh-react-refresh-webpack-plugin-virtual-5ef0209fe8/0/cache/@pmmmwh-react-refresh-webpack-plugin-npm-0.4.3-5375cf6b6f-718853bf7b.zip/node_modules/@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource.js)
Ancestor breaking the chain: @storybook/preset-create-react-app@virtual:ddccc941eb8b35cd4b898a64351d8bba4ecc85eb47e8f1b36dce7852d6c3635665e0fc5464861f723d175edb2248ce0fa54dfefb9b5e4d2fdaef4b2353c4aa82#npm:3.1.7

다음과 같은 패키지를 설치 후, 다시 기동하여 확인한다.

npm install -D  webpack-hot-middleware

lint Error

위와 같이 실행 후, yarn lint를 수행하면 아래 예시와 같이 에러가 발생한다.

/Users/user/Documents/mio/my-app/src/App.test.tsx
2:1 error There should be at least one empty line between import groups import/order
8:3 error Unsafe call of an `any` typed value @typescript-eslint/no-unsafe-call

/Users/user/Documents/mio/my-app/src/App.tsx
1:1 error There should be at least one empty line between import groups import/order

/Users/user/Documents/mio/my-app/src/index.tsx
2:1 error There should be at least one empty line between import groups import/order
7:1 error Caution: `ReactDOM` also has a named export `render`. Check if you meant to write `import {render} from 'react-dom'` instead import/no-named-as-default-member
11:34 error Insert `,` prettier/prettier
// ...SKIP

이 부분은 커스텀하여 정의된 lint 규칙과 스토리북과 cra에서 생성하여 정의한 코딩 스타일이 맞지 않아서 발생하는 부분이다.

그리고 아래의 구문에서 발생하는 에러는..

// App.test.tsx
expect(linkElement).toBeInTheDocument();

// Property 'toBeInTheDocument' does not exist on type 'JestMatchers<HTMLElement>'.ts(2339)
// 9:3 error Unsafe call of an `any` typed value @typescript-eslint/no-unsafe-call

yarn add -D @types/testing-library__jest-dom를 실행 후에 tsconfig.json에 다음과 같이 추가해주어 해결할 수 있다.

// tsconfig.json
"types": [
"@types/jest",
"@types/testing-library__jest-dom",
]