React, 리액트 CRA 초기세팅 가이드

라용·2022년 10월 3일
4

위코드 - 스터디로그

목록 보기
72/100

위코드에서 공부하며 정리한 내용입니다. 사진 출처, 위스터디

1. CRA 및 Third-Party Library 설치

1-1. CRA 를 통한 프로젝트 설치

프로젝트를 시작할 폴더에 진입한 후 터미널에 명령어를 입력해 설치합니다. 프로젝트 이름은 소문자(kebab-case)로 작성하는 게 일반적입니다.

$ npx create-react-app [프로젝트명]

1-2. Third-Party Library Setting

위 명령어로 생성한 폴더로 진입해 Third-Party Library 를 생성합니다.

// 해당 폴더로 진입하는 명령어
$ cd [프로젝트명]

1-2-1. Routing

라우팅 기능을 추가하기 위한 react-router-dom 을 설치합니다.

$ npm install react-router-dom

1-2-2. Styling

스타일링을 위한 라이브러리르 설치합니다. Sass, styled-components 등등

// Sass 설치
$ npm install sass

// styled-components & styled-reset
$ npm install styled-components styled-reset

1-2-3. ESLInt, Prettier

여러 작업자들의 코딩 스타일 일치를 위해 Lintter 로 ESLint 를 사용하고 Code Formatter 로 Prettier 를 사용합니다. ESLint 는 작성한 코드의 구문을 분석해 버그가 발생할 여지가 있거나, 불필요한 코드, 보안상 위험한 코드에 대한 경고를 줍니다. Prettier 는 자동으로 코드 스타일을 맞춰주는 보다 강력한 기능을 지원해 ESLint 와 함께 쓰입니다.

설치하는 방법은 크게 두가지로 VS Code Extention 과 NPM Package 를 사용합니다. 팀원 모두 각자 설치해서 동일한 개발환경을 구성하고 프로젝트를 진행합니다. 보통 두가지 방식으로 모두 설치할 것을 권장합니다. (.eslintrc, .prettierrc 등 설정파일을 활용하고 VS code 코드 입력 시 실시간 수정을 위해)

다만, CRA로 시작할 경우 pakage.json 에서 확인하는 ESLint 는 기본적으로 설치되어야 합니다.

// package.json

"eslintConfig" : {
	"extends": "react-app"
}

VS Code 의 익스텐션은 각각 검색해서 설치하면 되고, 설치 후 Settings 에가 각각의 Extention 설정이 적용될 범위를 정할 수 있습니다.

User - 로컬 유저 대상으로 사용 범위 설정, 해당 프로젝트 클론한 다른 사용자에게 적용 안됨
Workplace - 프로젝트 루트 경로에 .vscode 폴더를 생성하고 setting.json 을 해당 폴더 안에 생성합니다. 이 폴더가 git 에 함께 업로드되면 이 파일이 포함된 프로젝트 폴더를 받아서 사용하는 사람은 해당 설정값을 적용받습니다. 다만, 여기에 포함되는 설정은 eslint/prettier 관련 설정에 국한되지 않습니다. tab width 나 terminal 관련 설정 또한 포함되어 다른 팀원의 에디터에 영향을 줄 수 있으니 유의해야 합니다. 이러한 이유로 사용할 예정이라면 컨벤션에 맞게 작성하고, 그렇지 않을 예정이라면 컨벤션에 맞는 내용을 작성해서 사용하고 그렇지 않을 예정이라면 .gitignore 에 추가해두는 게 좋습니다.

npm 패키지 설치

CRA 에 eslint 가 내장되어있어 eslint를 추가 설치할 필요는 없고, eslint 추가 설정을 위한 패키지만 추가하면 됩니다. 설치 후 pakage.json 의 devDependencie 를 사용합니다.

$ npm install -D prettier eslint-config-prettier eslint-plugin-prettier

[참고] dependencies vs devDependencies
프로젝트에 필요한 외부 패키지들은 pakage.json에 담깁니다. node_modules 폴더에 담기는 패키지들은 용량이 크기 때문에 해당 파일의 로그만 담아서 업로드하고 npm 기반으로 작성한 프로젝트를 클론 받았을 때 pakage.json 의 정보를 기반으로 필요한 의존성들을 재설치합니다. 개발 단계에서 사용하는 패키지와 실제 프로젝트 빌드 후 사용하는 패키지는 다를 수 있고, eslint 나 prettier 는 개발 단에서만 사용하는 패키지이므로 빌드할 때 의존성에서 제외해 최종 결과물의 크기를 줄일 수 있습니다.

.vscode/setting.json

프로젝트 최상위에 .vscode 폴더를 생성하고 setting.json 파일을 만들어 아래 코드를 입력합니다.

// .vscode/settings.json

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "javascript.format.enable": false,
  "eslint.alwaysShowStatus": true,
  "files.autoSave": "onFocusChange"
}

.eslintrc

프로젝트 최상위에 .eslintrc 파일을 만들어 아래 코드를 입력합니다. 팀원이 맥 유저일 경우와 아 경우 세팅이 다르니 확인 후 적용하세요.

모두 맥 유저라면

// .eslintrc

{
  "extends": ["react-app", "plugin:prettier/recommended"],
  "rules": {
    "no-var": "warn", // var 금지
    "no-multiple-empty-lines": "warn", // 여러 줄 공백 금지
    "no-console": ["warn", { "allow": ["warn", "error"] }], // console.log() 금지
    "eqeqeq": "warn", // 일치 연산자 사용 필수
    "dot-notation": "warn", // 가능하다면 dot notation 사용
    "no-unused-vars": "warn", // 사용하지 않는 변수 금지
    "react/destructuring-assignment": "warn", // state, prop 등에 구조분해 할당 적용
    "react/jsx-pascal-case": "warn", // 컴포넌트 이름은 PascalCase로
    "react/no-direct-mutation-state": "warn", // state 직접 수정 금지
    "react/jsx-no-useless-fragment": "warn", // 불필요한 fragment 금지
    "react/no-unused-state": "warn", // 사용되지 않는 state
    "react/jsx-key": "warn", // 반복문으로 생성하는 요소에 key 강제
    "react/self-closing-comp": "warn", // 셀프 클로징 태그 가능하면 적용
    "react/jsx-curly-brace-presence": "warn" // jsx 내 불필요한 중괄호 금지
  }
}

윈도우 유저가 있다면,

// .eslintrc

{
  "extends": ["react-app", "plugin:prettier/recommended"],
  "rules": {
    "no-var": "warn", // var 금지
    "no-multiple-empty-lines": "warn", // 여러 줄 공백 금지
    "no-console": ["warn", { "allow": ["warn", "error"] }], // console.log() 금지
    "eqeqeq": "warn", // 일치 연산자 사용 필수
    "dot-notation": "warn", // 가능하다면 dot notation 사용
    "no-unused-vars": "warn", // 사용하지 않는 변수 금지
    "react/destructuring-assignment": "warn", // state, prop 등에 구조분해 할당 적용
    "react/jsx-pascal-case": "warn", // 컴포넌트 이름은 PascalCase로
    "react/no-direct-mutation-state": "warn", // state 직접 수정 금지
    "react/jsx-no-useless-fragment": "warn", // 불필요한 fragment 금지
    "react/no-unused-state": "warn", // 사용되지 않는 state
    "react/jsx-key": "warn", // 반복문으로 생성하는 요소에 key 강제
    "react/self-closing-comp": "warn", // 셀프 클로징 태그 가능하면 적용
    "react/jsx-curly-brace-presence": "warn", // jsx 내 불필요한 중괄호 금지
    "prettier/prettier": [
      "error",
      {
        "endOfLine": "auto"
      }
    ]
  }
}

.prettierrc

프로젝트 최상위에 .prettierrc 파일을 만들어 아래 코드를 입력합니다.

// .prettierrc

{
  "tabWidth": 2, 
  "endOfLine": "lf", 
  "arrowParens": "avoid", 
  "singleQuote": true,
}

파일을 추가할 때 프로젝트 폴더를 오픈하지 않고 프로젝트 상위 폴더를 오픈하면 세팅들이 정상 작동하지 않습니다. 아래 이미지 위치를 참고하세요.

문제 해결

서로 다른 포맷터는 extention으로 설치할 경우 출동이 날 수 있으므로 하나만 남기고 삭제합니다. (beautiful 과 prettier 가 동시에 있을 경우)
context.getPhysicalFilename is not a function 에러가 발생할 경우 파일 버전 문제이므로 아래 명령어를 싱핼해서 해결합니다. (npm 업데이트 하고 pakage 삭제 후 재설치 하는 과정)

npm install npm@latest -g
npm -v
npm uninstall -D eslint-config-prettier eslint-plugin-prettier
npm install -D eslint-config-prettier eslint-plugin-prettier

+파일 구조 정리 (간단 코멘트)

public 에서 favicon, index.html 빼고 삭제

src 에는 Index.js 만 두고 나머지 삭제

그리고 index.html 에서 불필요한 주석이나 파일 연결을 지워서 아래처럼

index.js 도 들어가서 불필요한 부분 삭제하고 아래처럼

이렇게 기본 파일만 남은 상태에서 한번 커밋
git add.
git commit -m "Delete Unnessary Files"

2. CRA 추가 폴더 및 파일 구성

2-1. public/

2-1-1. public/data/

목데이터를 관리하는 폴더입니다. 깃 추적을 위해 임시파일을 만들어 둡니다.

2-1-2. public/images/

js 파일 안에서 사용하는 이미지를 관리하는 폴더입니다. Images 폴더 하위에 바로 이미지 파일을 넣는 것보단 폴더 안에 Nav, ProductDetail 폴더를 만들어서 이미지를 페이지별로 관리하는 것이 좋습니다. 초기 세팅이라 별도 컴포넌트 분류가 없다면 Images 까지만 만들고 깃 추적을 위해 파일 하나를 만들어 넣어둡니다.

js 파일에서 public/images 로 접근할 때는 절대경로를 사용하면 됩니다.

// ProductDetail.js

import React from 'react';

const ProductDetail = () => {
  return <img src="/images/PruductDetail/product1.jpg" alt="프로덕트1" />;
};

export default ProductDetail;

2-1-3. public/favicon.ico

웹 브라우저의 상단 탭에 표시되는 아이콘 입니다.

2-2. src/

src 안의 폴더 이름은 리액트에 생성한 컴포넌트가 바로 들어 있는 폴더라면 파스칼 케이스로 작성합니다.

2-2-1/ src/assets/images/

background-image 속성처럼 css 에서 이미지 삽입할 때 js 파일처럼 절대 경로로 public 폴더에 접근할 수 없습니다. 이 때는 src/assets/images 에서 관리해서 절대 경로 혹은 상대 경로를 사용해야 합니다. (css 의 절대경로는 src)

//Bad
.feedImage {
  background-image: url('/images/heart.jpg');
}

//Good
.feedImage {
  background-image: url('../../assets/images/heart.jpg');
}
.feedImage {
  background-image: url('/assets/images/heart.jpg');
}

폴더 구성은 아래와 같습니다. Footer 나 Main 같은 분류가 아닌 images 폴더만 만들어 둡니다.

2-2-2. src/components/

components 폴더에는 Nav, Footer 등 여러 페이지에서 공통으로 사용하는 컴포넌트를 관리합니다. 각 컴포넌트에 개별적으로 사용하는 컴포넌트라면 이 곳에서 관리하지 않고 해당 컴포넌트와 같은 레벨로 폴더를 생성해서 컴포넌트를 저장, 관리합니다.

2-2-3. src/pages/

pages 폴더는 하나의 페이지를 구성하는 컴포넌트들을 관리하는 폴더입니다.

2-2-4. src/styles/

프로젝트에 공통으로 적용할 스타일 파일을 생성합니다. Sass 의 경우 css 속성을 초기화하는 reset.scss 와 공통 css 속성을 정의하는 common.scss, 공통으로 반복해서 사용하는 css 속성 변수를 정리하는 variables.scss 파일을 만듭니다.

styled-components 를 사용할 경우 공통 css 속성을 정의하기 위한 GlobalStyle.js 파일을 만들고, 반복해서 사용하는 변수 설정을 담을 theme.js 파일을 만듭니다.

2-2-6. src/Router.js

프로젝트에 사용할 Router 파일을 구성합니다.

// src/Router.js

import React from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Login from './pages/Login/Login';
import Main from './pages/Main/Main';

const Router = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Login />} />
        <Route path="/main" element={<Main />} />
      </Routes>
    </BrowserRouter>
  );
};

export default Router;

이때 import 하는 컴포넌트는 아래와 같이 간단히 세팅되어야 합니다.

2-2-7. src/index.js

render() 메서드를 통해 그려주는 컴포넌트를 Router 로 설정합니다.
Sass 는 아래와 같이 작성하고, (common 과 reset 만 연결하고 variable 은 각 scss 파일에 연결해서 써야 함)

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import Router from './Router';
import './styles/reset.scss';
import './styles/common.scss';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Router />);

styled-components 는 ThemProvider 컴포넌트로 theme 을 전역에 props 로 넘겨주고, GlobalStyle 컴포넌트로 전역에 공통으로 필요한 스타일을 적용합니다.

// src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import { ThemeProvider } from 'styled-components';
import GlobalStyle from './styles/GlobalStyle';
import theme from './styles/theme';
import Router from './Router';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <ThemeProvider theme={theme}>
    <GlobalStyle />
    <Router />
  </ThemeProvider>
);

2-2-8. src/config.js

API는 config.js 파일에 일괄적으로 관리하면서 import, export 통해 사용하면 좋습니다. 백엔드 서버 IP 가 변경되면 fetch 함수를 일일이 찾아서 수정해주지 않아도 됩니다.

// src/config.js
const BASE_URL = 'http://10.58.5.151:8000'
export const GET_PRODUCT_API = `${BASE_URL}/products`

// 사용하는 컴포넌트
import { GET_PRODUCT_API } from '../../../config.js';
...
fetch(`${GET_PRODUCT_API}/5`).then(...).then(...);

2-3. .eslintcache

eslint 는 lint 검사를 할 때마다 .eslintcache 파일을 생성하고 업데이트 합니다. .eslintcache 파일 안에 기존 lint 검사 내역을 저장해서 매번 전체 파일을 검사하는 것이 아니라 매번 변경된 파일에 대해서만 lint 검사를 할 수 있습니다. 이 파일은 git 으로 관리할 필요가 없으므로 .gitignore 에 추가해야 합니다.

// .gitignore

.eslintcache

+초기 세팅 파일 과 폴더는 아래 도식으로 확인해보세요.

profile
Today I Learned

0개의 댓글