20210605 React03 : CRA, ESLint, Prettier, Husky, Lint-staged, CRA코드 이해하기, React Developer Tools, React-Router-Dom, SPA 라우팅 과정, Router 구현하기
React 03
Create React App
- 본격적으로 App 만들기
 - Create React App -> 줄여서 CRA 라고 부름
 - create-react-app.dev : React app을 만드는 CLI 툴 소개
    
- 편하게 프로젝트를 생성할 수 있게 도와주고, 그외 여러가지 기능들을 제공함
 
 
CRA - 명령어
- npx 명령어 : npm 5.2.0 이상부터 함께 설치된 커맨드라인 명령어
 - 앱생성 명령어로 만들어진 프로젝트는 노드 (npm) 기반의 프로젝트임
 
- 
    
npx create-react-app 프로젝트이름: 프로젝트 생성 - 
    
npm start: dev server 실행 (변경사항 바로 반영 됨) - 
    
npm run build: build(compile) 해서 production을 만듦 (변경사항 반영안됨, 다시 빌드 해야함)npm i serve -g: serve 패키지 전역 설치npx serve -s build: build한 production을 file sever로 실행시킴- s옵션 : 어떤 라우팅을 요청해도 index.html을 응답하도록 함
 - (npx로 일시적으로 사용 -> 실행할 때 마다 가져와야 함)
 
 
npm run test: jest기반으로 test code들이 실행이 되어 앱 test를 진행함- test 코드가 있는 곳 및 파일 (test시 해당 파일을 추적해서 test함)
        
__test__폴더 안의 js 파일.test.js로 끝나는 파일.spec.js로 끝나는 파일
 
- test 코드가 있는 곳 및 파일 (test시 해당 파일을 추적해서 test함)
        
 
npm run eject: 프로젝트 환경 설정을 custom하게 조정하는 경우 CRA에서 제공하지 않는 사항을 ejcet시켜서 자유롭게 변경시킬 수 있음- (단, 꺼내면 오류가 많이 생길수 있어서 CLI 범주내에서 해볼려고 함), 결국엔 CRA 라이브러리를 사용하지 않겠다는 것임
 - 이렇게 eject 함으로써 CRA에서 사용되던(의존하고 있던) 라이브러리가 설치되고, 해당 라이브러리들의 설정 config 파일이 생성되면서 여러 옵션을 변경하여 custom이 가능함
 
{
  "name": "tic-tac-toe",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    // --- testing ----
    "@testing-library/jest-dom": "^5.13.0",
    "@testing-library/react": "^11.2.7",
    "@testing-library/user-event": "^12.8.3",
    // --- 핵심 모듈 ----
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    // -- create-react-app --
    "react-scripts": "4.0.3", // 개발환경, build 작업
    // -- SEO 같은 느낌 --
    "web-vitals": "^1.1.2" // google에서 사이트 경험 측정, 개선용
  },
  "scripts": {
    // CLI scripts
    "start": "react-scripts start", // dev server
    "build": "react-scripts build", // production
    "test": "react-scripts test", // jest test
    "eject": "react-scripts eject" // custom library
  },
  "eslintConfig": {
    "extends": ["react-app", "react-app/jest"]
  },
  "browserslist": {
    "production": [">0.2%", "not dead", "not op_mini all"],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}
CRA를 통한 build 원리
- 일단, webpack bundler를 사용
 - webpack이 파일 확장자에 맞는 loader에게 build를 위임 (webpack에서 loader들을 가져와서 연결)
    
- JS,JSX 파일 -> babel-loader가 complie (babel config를 참조해서) -> build 용 파일
 - css 파일 -> css-loader가 compile (css 관련 처리 도구의 config를 참조해서) -> build용 파일
 
 - webpack이 여러가지 종류의 loader들이 연결될 수 있게 지휘자 역할을 함
 
ESLint
- CRA를 설치하면 기본적으로 설치가 됨
 - Javascript, JSX의 코딩 스타일을 통일하기 위한 가이드를 제공해 줌
    
npm i eslint -D: eslint Dev dependencies 로 설치npx eslint --init: eslint 로 check할 옵션들 선택해서 초기화 시켜줌npx eslint 파일명: eslint로 설정한 규칙에 어긋 나는지 확인함- ESLint vscode 확장 프로그램 설치 : 직접 eslint를 실행할 필요 없이 compile해서 미리 오류를 빨간선으로 보여줌
 npx eslint 파일명 --fix: 규칙에 어긋나는 것을 자동으로 고쳐줌
 - 기본적으로 CRA에는 eslint를 의존하고 있기 때문에 ESLint vscode extension만 설치하면 알아서 코딩 스타일 오류를 찾아줌
 - eslint에 대한 설명
 
Prettier
- 의도적으로 수정하는 code formatter
 npm i prettier -Dnpx prettier 해당 파일: 해당 파일에 대한 format을 추천npx prettier 해당 파일 -write: 해당 파일에 대한 format 추천을 코드에 적용함- 매번 이렇게 하기 힘들기 때문에 vscode extension으로 prettier를 설치함
 - ESLint와 Prettier에 대한 충돌을 막는 패키지 -> eslint-config-prettier
    
- Prettier에서 불필요하거나 Prettier와 충돌 할 수 있는 모든 규칙을 끔
 
 
Husky
- git hook을 쉽게 사용하게 해줌
 - commit 직후에, push 직후에 무엇을 할지 정해 줄수 있음
 git init으로 초기화를 해주고, Husky를 설정해야 하기 때문에 git init 먼저하고 Husky를 설치함
초기 세팅 명령어
npm i husky -Dnpx husky install: git hook을 설치함npx husky add .husky/pre-commit "npm test"
npx husky-init: 한번에 husky install, pre-commit 파일 만들기 까지 끝냄git add -A: all 옵션임- 즉, pre-commit 공간에 prettier, eslint, test 등의 실행코드를 넣어 commit 전에 한번더 확인 시킬 수 있고 문제가 있으면 commit을 중단 하게 되어 코드 점검을 하게 됨
 
lint-staged
- stage된 파일이 있으면 다른 라이브러리의 명령어를 수행하겠다.
 npx husky-init-> pre-commit파일npx lint-staged로 변경npm i lint-staged -Dnpm i prettier -D- lint-staged 설정
 - vscode 설정 - format - Format on Save 체크 해제
 
// package.json
{
  "lint-staged": {
    "**/*.js": ["eslint --fix", "prettier --write", "git add"]
  }
}
- 이를 통해서 모든 커밋으로 올라온 코드들이 강제로 잘 정돈된 상태로 올라오게 됨
 
CRA 코드 이해하기
public 폴더: static한 파일을 serve 하는 폴더 (favicon, index.html, images, …)src 폴더App.test.js: test 샘플 파일index.js: 메인 진입점 (entry)index.css: 메인 진입점의 CSS로 common css 같은 느낌App.js: App 컴포넌트 (funtion component)App.css: App 컴포넌트 CSS
// index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css"; // 기본적인 common CSS
import App from "./App"; // App Component
import reportWebVitals from "./reportWebVitals";
// main 진입
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);
// App.js
import logo from "./logo.svg"; // logo image
import "./App.css"; // App Component CSS
function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}
export default App;
React Developer Tools
- 브라우저에서 React Compnent를 debuging 하는 Tool임
 - 크롬 익스텐션으로 React Developer Tools 설치하여 사용가능 함
 - React로 구성된 웹페이지의 components 분석이 가능하다.
    
- props, source위치 등을 알수 있음
 - profiler 탭을 사용하면 컴포넌트가 얼마정도 랜더가 되는지도 볼수 있음 (성능을 올리는 지표)
 
 
React 라우팅 이해하기 (react-router-dom)
- 과거 여러 페이지들을 다루는 경우 페이지가 이동하면, server에서 해당 URL에 대한 페이지를 요청해서 가져왔음
 
- 현재는 SPA (Single Page Application)으로 서버로 부터 큰 앱을 하나 받아오고 browser에서 어떤 페이지를 보여줄지 결정함
 
SPA 라우팅 과정
- 브라우저에서 최초에 
/경로로 요청 - -> Server에서 React Web App을 보내줌
 - -> React web App 에서 
/경로에 맞는 컴포넌트 출력 - -> React web app에서 다른 페이지(경로)로 이동하는 동작을 수행
 - 
    
-> 새로운 경로에 맞는 컴포넌트 출력
 - 그래서, URL에 대한 어떤 컴포넌트를 보여줄지를 결정하는 로직이 필요함
    
- React-Router-Dom
 
 
React-Router-Dom
npm i react-router-dom로 설치- CRA에 기본 내장된 패키지가 아님
 - Facebook 공식 패키지는 아님
 - 가장 대표적인 라우팅 패키지 임
 - 예시)
    
/=> Home 컴포넌트/profile=> Profile 컴포넌트/about=> About 컴포넌트
 
Router 구현하기
import { BrowserRouter, Route } from "react-router-dom";
import "./App.css";
import About from "./pages/About";
import Home from "./pages/Home";
import Profile from "./pages/Profile";
function App() {
  return (
    <BrowserRouter>
      <Route path="/" exact component={Home} />
      <Route path="/profile" component={Profile} />
      <Route path="/about" component={About} />
    </BrowserRouter>
  );
}
export default App;
src 폴더->pages 폴더생성 -> 구현할 Route 이름으로 JSX 파일들 생성 (예. Home.JSX)App.js파일에서 react-router-dom을 import하여 BrowserRouter, Route 컴포넌트를 활용- React-Router-Dom에서 제공하는 
Route 컴포넌트에 경로와 컴포넌트를 설정하여 나열해 줌 BrowserRouter 컴포넌트로 Route들을 감싸줌- 브라우저에서 요청한 경로에 Route의 path가 들어 있으면 해당 component를 보여줌
    
/,/profile,/about경로를 보면/profile에는/이 들어 있어서 두개다 보여주고,/about도 마찬가지로/가 들어 있어 두 페이지의 component들 모두 보여주게 됨- 그래서, 완전히 경로가 같아야 같은 것이고 포함관계를 없애 고자 하는 경우 
exact키워드를 사용함