🧐 회고

1. 배운 점

  • npm과 npx의 차이: npm은 패키지 설치 및 관리를 위한 도구이며, npx는 패키지를 실행하는 데 특화된 도구라는 점을 알게 되었다. 특히, npx는 설치 없이도 패키지를 즉시 실행할 수 있어 편리하다.
  • 가상 돔의 원리와 사용 이유: 리액트에서 가상 돔은 DOM 조작을 효율적으로 하기 위해 사용되며, 이를 통해 성능을 최적화한다는 점을 이해했다.
  • 트랜스파일러의 역할: 트랜스파일러가 JSX 코드를 React.createElement 호출로 변환하여 브라우저에서 이해할 수 있는 코드로 만드는 역할을 한다는 것을 배웠다.

2. 앞으로 더 조사해볼 내용

  • CRA보다 Vite가 빠른 이유: Vite의 빠른 빌드 속도의 비결을 알아보고, CRA와 비교했을 때 어떤 장점이 있는지 조사할 필요가 있다.
  • Compiler 및 Webpack: 컴파일러와 웹팩의 기능과 역할을 더 깊이 이해하고, 이를 통해 프로젝트 설정 및 최적화 방법을 학습하고자 한다.
  • SWC(Speedy Web Compiler): SWC가 기존의 Babel을 대체할 수 있는지, 그리고 어떤 장점이 있는지에 대해 더 알아볼 예정이다.
  • 리액트에서 말하는 서버란?: 리액트의 서버사이드 렌더링(SSR) 개념과 실제로 '서버'가 어떤 역할을 하는지 조사할 계획이다.
  • 런타임 오버헤드란?: 런타임 오버헤드의 개념과 이를 줄이는 방법을 학습하고, 성능 최적화 방안을 찾아볼 예정이다.

3. 앞으로 적용해야겠다고 느낀 점

  • npx와 npm의 상황별 사용: 상황에 맞게 npx와 npm을 활용하여 효율적으로 패키지를 관리하고 실행할 것이다.
  • Tailwind 사용: 스타일링을 더욱 체계적이고 일관되게 하기 위해 Tailwind CSS를 사용해볼 것이다.

4. 학습 평가 및 다짐/목표

이번 수업을 통해 최신 웹 기술과 도구에 대해 이해를 할 수 있었고, 특히 리액트 관련 성능 최적화 방법에 대해 깊이 있게 배웠다. 내일부터 본격적으로 배우게 될 Tailwind와 리액트가 기대된다.


📒 학습 내용 정리

Section 00 - 리액트에서 자주 쓰는 ES6 문법들

  1. const, let
  2. 템플릿 문자열
  3. 객체 리터럴
  4. 화살표 함수
  5. 비구조화 할당 -> 사용 예시
  6. 스프레드 연산자 -> 사용 예시

Section 01 - 리액트 준비

npm, npx, yarn 이해하기

💡 실무 팁

  • 보통 무언가를 설치할 때 지역적으로 설치하는 것이 좋으나 node.js, npm은 전역으로 설치하는 게 좋음
  • 하나의 프로젝트에 하나의 프로젝트 매니저만 사용할 수 있음

npm (Node Package Manager)

Node.js의 기본 패키지 관리자

📍패키지(package): 소프트웨어 개발에서 재사용할 수 있도록 묶어놓은 코드의 집합, 특정 기능이나 기능 세트를 구현한 라이브러리, 프레임워크, 도구 등을 포함할 수 있음

  • Node.js와 함께 설치됨
  • Node.js 애플리케이션의 종속성을 관리하고 패키지를 설치, 업데이트, 제거하는 데 사용함
  • .npmrc 파일을 통해 설정 가능
  • package-lock.json 파일을 사용하여 패키지 버전을 고정

npx(Node Package Execute)

Node 패키지를 실행하는 도구

  • Node.js와 함께 설치됨
  • npm으로 로컬 또는 글로벌로 다운로드 받지 않은 패키지도 실시간으로 설치하여 실행할 수 있음
  • 개발 의존성을 줄이고 필요한 경우 패키지를 설치하여 실행
  • 임시적으로 패키지를 실행할 때 유용함

📍개발 의존성(Development Dependency): 개발 과정에서 필요한 도구와 라이브러리로, 애플리케이션의 실제 배포 및 실행에는 필요하지 않음, 개발 의존성을 줄이는 것은 프로젝트의 복잡성을 줄이고, 빌드 및 배포 과정을 최적화하며, 보안을 강화하고, 유지보수 비용을 절감하는 데 중요한 역할을 함

➕ 참고하면 좋은 글

npm 과 npx 는 뭐가 다를까 ?

Yarn

페이스북에서 개발한 패키지 매니저

  • 패키지 설치, 삭제 등에 있어서 병렬로 처리함 -> 성능 향상
  • yarn.lock 파일을 사용하여 더 확정적인 의존성 트리 생성
  • 모든 패키지에서 지원하지 않으므로 확장성 면에서 npm보다 떨어짐
  • 오프라인 모드 지원: 이전에 설치된 패키지를 다시 다운로드하지 않고 설치 가능

➕ 더 알아볼것

최신 패키지 매니저 중 Bun과 PNPM이라는 것도 있음

출처: NPM vs Yarn vs PNPM: Which Package Manager is Right for You?

패키지 버전 읽는 법

  • Major : 주요 릴리즈
    • 주로 이전 버전과 호환성을 깨트릴 정도의 중요한 패치의 경우
  • Minor: 새로운 기능
    • 이전 버전과 호환성은 유지함
  • Patch: 버그 수정
  • 옵셔널
    • 특정 버전 뒤에 문자열로 된 의미를 부여하고 싶을 때 사용

리액트 프로젝트 생성 방법

💡 실무 팁

  • 프레임 워크를 시작할 때 설치 방법은 공식 사이트의 가이드를 따르는 것이 좋음
  • VS Code에서 작업할 폴더의 루트에 설치하는 것이 가장 좋음
  • package-lock.json파일은 npm install 시 자동으로 생성 되므로 .gitignore파일에 추가 하자
    • npm install: package.json 파일을 참고해서 node_modules, package-lock.json을 자동으로 생성함

Create React App

가장 고전적인 방법, 더이상 권장되지 않음

프로젝트 생성 방법

1. npx

npx create-react-app my-app -> (npm 레지스트리의 최신 버전 실행)

  • 공식 사이트에서 권장하는 방법
  • 직접 패키지를 설치하고 업데이트를 하지 않더라도, npm 레지스트리에 올라가 있는 최신 버전을 실행
  • 만약 해당 패키지가 이미 로컬에 설치되어 있다면, 그 버전을 사용하므로 주의 할것

2. npm (사용x)

npm install -g creact-react-app -> (npm 레지스트리의 최신 버전 설치)
create-react-app my-app -> (설치 당시의 버전 실행)

  • 설치된 create-react-app 버전이 시간이 지남에 따라 최신 상태가 아닐 수 있으므로 수동 업데이트하지 않는 한 새로운 버그 수정이나 기능 업데이트를 놓칠 수 있음

Vite

근래에 가장 주목 받고 있는 프로젝트 생성 방법

프로젝트 생성 방법

npm create vite@latest

  • 공식 사이트에 명시 돼 있는 방법
  • npm create 명령어는 내부적으로 npx 패키지를 활용하여 프로젝트를 생성해주기 때문에 항상 최신의 버전의 패키지를 사용함

➕ 더 알아볼것

Section 02 - 리액트 시작하기

주요 폴더 및 파일

node_modules/:

  • 프로젝트의 모든 의존성을 포함함
  • npm install 명령어 통해 package.json 파일에 명시된 모든 의존성을 이 폴더에 설치함
  • 일반적으로 버전 관리 시스템(Git 등)에 포함되지 않음

public/:

  • 정적 파일을 포함하는 폴더
  • 웹팩의 영향을 받지 않음
  • 이 폴더 안의 파일은 빌드 과정에서 그대로 복사되어 최종 빌드에 포함됨

src/:

  • 애플리케이션의 소스 코드가 포함된 폴더
  • assets/: 이미지, 폰트 등의 정적 자산을 포함할 수 있는 폴더, public/과 달리 웹팩의 영향을 받음
  • App.jsx: 메인 애플리케이션 컴포넌트 파일, React 컴포넌트 구조의 시작점
  • main.jsx: 애플리케이션의 진입점 파일, ReactDOM을 사용하여 App 컴포넌트를 HTML에 렌더링함

index.html:

  • public/ 또는 최상위 디렉토리에 있는 HTML파일
  • Vite는 이 파일을 기반으로 빌드하고 애플리케이션을 시작함
  • 개발 서버가 구동되면 가장 먼저 불러와지는 파일(?)

package.json

  • 프로젝트의 메타데이터와 의존성을 정의하는 파일
  • 스크립트, 의존성, 개발 의존성, 프로젝트 이름, 버전 등의 정보가 포함됨

vite.config.ts

  • Vite의 다양한 설정을 커스터마이즈할 수 있는 설정 파일

➕ 더 알아볼것

  • Compiler 및 Webpack은 무엇인가?
  • SWC(Speedy Web Compiler)는 무엇인가?
    • 자바스크립트 프로젝트의 컴파일과 번들링에 모두 사용될 수 있는 빌드 툴
    • 기존에 사용하던 Babel을 대체할 수 있음
    • 최근 Next.js 팀에서 권장하고 있어 주목 받고 있는 빌드 툴

리액트를 사용하는 이유

1. 강력한 커뮤니티와 광범위한 생태계

  • 국내외로 인기가 많아 매우 큰 커뮤니티를 보유하고 있어 관련 자료가 많아 학습 및 문제 해결이 쉬움
  • 다양한 서드파티 라이브러리와 도구를 지원함

2. 강력한 컴포넌트 기능

리액트를 가장 인기있는 프레임워크로 만들어 준 핵심 기능

  • 컴포넌트: React에서 웹의 구성 요소를 작은 단위로 분할하여 재사용 가능한 독립적인 코드로 작성한 것
  • 컴포넌트를 활용하면 반복적인 웹 구성 요소를 효율적으로 관리할 수 있으며 코드의 가독성과 유지보수성을 높일 수 있음

3. Virtual DOM (가상 돔)

React는 SPA 구조에서 빈번한 DOM 조작으로 인한 성능 문제를 해결하기 위해 가상 돔을 사용함

CRP(Critical Rendering Path)

웹 페이지가 사용자에게 표시되기까지의 과정. CRP는 페이지 로드 성능에 중요한 영향을 미침

  • HTML 파싱 및 DOM 생성: 브라우저는 HTML 문서를 파싱하여 DOM(Document Object Model)을 생성함

  • CSS 파싱 및 CSSOM 생성: CSS 스타일시트를 파싱하여 CSSOM(CSS Object Model)을 생성함

  • JavaScript 실행: JavaScript는 DOM이나 CSSOM을 수정할 수 있으며, 이를 통해 렌더링에 영향을 줄 수 있음

  • 렌더 트리 생성: DOM과 CSSOM을 결합하여 렌더 트리를 생성, 이 트리는 실제로 렌더링할 요소만 포함함

  • 레이아웃: 렌더 트리를 기반으로 각 요소의 크기와 위치를 계산함

  • 페인팅: 최종적으로 계산된 정보를 사용하여 화면에 픽셀을 그림

  • Reflow와 Repaint: 페이지 이동이나 JavaScript 조작으로 CRP가 다시 발생하며, Reflow와 Repaint는 성능 비용이 큼. 따라서 이를 최적화하는 것이 중요함

최적화 예시

  • 최적화 전
    이 코드는 1000개의 <li> 요소를 추가할 때마다 Reflow와 Repaint가 1000번 발생함 -> 성능 저하
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      function createDOM() {
        console.time();
        const ulEl = document.querySelector('ul');
        for (let i = 0; i < 1000; i++) {
          ulEl.innerHTML += `<li>${i}</li>`;
        }
        console.timeEnd();
      }
    </script>
  </head>
  <body>
    <button onClick="createDOM()">추가</button>
    <ul></ul>
  </body>
</html>
  • 최적화
    DOM 조작을 최소화하여 성능을 개선할 수 있음. 여기서는 모든 <li> 요소를 한 번에 추가하여 Reflow와 Repaint를 한 번으로 줄임
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      function createDOM() {
        console.time();
        const ulEl = document.querySelector('ul');
        let liEl = '';
        for (let i = 0; i < 1000; i++) {
          liEl += `<li>${i}</li>`;
        }
        ulEl.innerHTML = liEl;
        console.timeEnd();
      }
    </script>
  </head>
  <body>
    <button onClick="createDOM()">추가</button>
    <ul></ul>
  </body>
</html>

리액트에서 Virtual DOM의 역할

JavaScript만으로 최적화하는 과정은 복잡하고 어렵기 때문에 React와 같은 프레임워크가 등장함
프레임워크는 이런 최적화를 자동으로 처리할 수 있으며, React는 Virtual DOM을 사용하여 효율적으로 DOM을 조작함

출처: What is Diffing Algorithm ? - GeeksforGeeks

  • Diffing & Reconciliation: Virtual DOM은 메모리 내에서 가상의 DOM을 생성하고, 실제 DOM과 비교하여 변경이 필요한 최소한의 부분만 업데이트함
    이를 통해 Reflow와 Repaint의 비용을 최소화하며 이 과정을 Diffing & Reconciliation라고 함

➕ 더 알아볼것

Batch Update는 무엇인가?

한계

Virtual DOM도 성능 비용이 있으며 React는 내부적으로 이러한 성능을 최적화하지만, 모든 경우에 완벽한 최적화를 보장하지는 않음

React에서 UI 요소 작성 방법

1. CreateElement

  • createElement 함수를 사용해서 모든 React 컴포넌트와 엘리먼트 생성 가능
  • JSX 없이 순수한 JavaScript 코드로 요소를 생성
  • 초기에는 JSX가 없었고, 개발자들은 createElement를 사용해 모든 요소를 수동으로 작성함
import React from 'react';
import ReactDOM from 'react-dom';

// React.createElement를 사용하여 컴포넌트 정의
const element = React.createElement(
  'div', // 태그 이름
  { className: 'greeting' }, // 속성
  'Hello, world!' // 자식 요소(내용)
);

// 해당 컴포넌트를 DOM에 렌더링
ReactDOM.render(
  element,
  document.getElementById('root')
);

2. JSX (Javascript XML)

  • createElement를 사용하는 방식은 번거롭고 가독성이 떨어짐

  • 페이스북 팀은 개발자들이 더 익숙한 HTML과 유사한 문법을 사용해 React 컴포넌트를 작성할 수 있는 JSX를 도입

  • JSX는 개발 편의성을 크게 높였고, React의 채택을 가속화하는 데 중요한 역할을 함

  • JSX는 브라우저에서 직접 실행할 수 없는 문법이기 때문에, Babel과 같은 트랜스파일러가 필요함

    • 트랜스파일러는 JSX 코드를 React.createElement 호출로 변환하므로 JSX와 React.createElement는 서로 상호 보완적인 관계에 있음
    • CRA: react-scripts 패키지(스크립트 모음으로, 프로젝트를 설정하고 관리하는 데 필요한 웹팩, 바벨과 같은 스크립트가 포함되어 있음)
    • Vite: @vitejs/plugin-react(-swc) (웹 팩과 바벨의 역할을 하는 패키지)
  • 주요 문법 특징

    • 단일 루트 태그: 모든 JSX 표현식은 하나의 루트 태그로 감싸야 함. 다중 요소를 반환할 때는 <React.Fragment> 또는 <></>를 사용할 수 있음
    • 태그 규칙: 여러 줄의 JSX 코드를 반환할 때는 소괄호로 감싸야 하며, 빈 태그는 반드시 닫아야 함
    • 표현식 사용: JSX 내부에서는 중괄호 {}를 사용하여 JavaScript 표현식을 포함할 수 있음 예를 들어, <h1>Count: {10 * 2}</h1>와 같이 작성할 수 있음
    • 컴포넌트 명명 규칙: 함수형 컴포넌트는 대문자로 시작해야 함. 이는 React가 컴포넌트를 구별하는 방식임
    • 클래스 속성: HTML에서 class 속성은 JSX에서 className으로 사용됨. 이는 JavaScript의 예약어인 class와의 혼동을 피하기 위함임

컴포넌트 CSS 스타일링

리액트에서 컴포넌트에 CSS 스타일을 적용하는 방법에는 여러 가지가 있음

인라인 스타일 (Inline Style)

컴포넌트의 JSX 내에서 style 속성을 통해 직접 스타일을 지정하는 방법

  • 자바스크립트 객체로 스타일을 정의하므로, CSS 속성명은 카멜 케이스로 표기해야 함
const App = () => {
  return (
    <div>
      <h1 style={{ fontSize: "30px", color: "#ed4848", textDecoration: "line-through" }}>
        Hello World!
      </h1>
    </div>
  );
};

export default App;

외부 스타일 (External Stylesheet)

별도의 CSS 파일에 CSS 코드를 작성하고, 리액트 컴포넌트 파일과 연결해서 사용하는 방법

  • 일반적으로 모든 컴포넌트에 영향을 미치는 전역 스타일은 main.tsx와 같은 파일에 import

CSS Modules

각 클래스 이름을 로컬 범위로 한정시켜 스타일 충돌을 방지하는 방법

  • 스타일 파일명은 .module.css 확장자를 사용하며, 컴포넌트에서 import하여 사용함
  • 파일은 컴포넌트가 있는 위치에 만들며 파일명은 컴포넌트 이름과 똑같이 짓는 것이 관례임

Tailwind CSS

대표적인 Atomic CSS 라이브러리, 클래스 이름만으로 스타일을 적용할 수 있음

  • 설치 방법
  • 장점: 커스터마이즈 가능, 불필요한 CSS를 줄여 파일 크기를 최소화할 수 있음
  • 단점: 처음에는 클래스 이름이 혼란스러울 수 있으며, HTML이 복잡해질 수 있음

CSS-in-JS

CSS-in-JS는 자바스크립트 파일 내에서 스타일을 정의하고, 컴포넌트와 밀접하게 결합하여 사용하는 방법

  • 주요 라이브러리로는 Styled Components, Emotion, Vanilla Extract, Linaria 등이 있음

➕ 더 알아볼것

리액트에서 말하는 서버는 뭘까?
런타임 오버헤드란?
dependency vs devDependency


참고 자료

——————————————————————————
본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프로젝트 캠프 : Next.js 2기 과정(B-log) 리뷰로 작성 되었습니다.

profile
아이디어와 구현을 좋아합니다!

0개의 댓글