리액트 프로젝트의 개발 환경 설정

HTML, CSS JavaScript 프로젝트에 리액트를 추가하는 방법

웹사이트에 React 추가

React는 처음부터 점진적으로 도입할 수 있게 설계되었다. 그래서 React는 필요한 만큼만 사용하면 된다. 아마 기존 페이지에 "상호작용'이라는 조미료를 첨가하기만 하고 싶을 수도 있다. 이럴 때 React 컴포넌트를 쓰면 좋다.

 

오늘날 웹사이트의 대부분은 싱글 페이지가 아니고 그래야 할 필요도 없다. 빌드 도구 없이 몇 줄의 코드만으로 웹 사이트의 작은 부분에 먼저 React를 도입해보아라. React의 비중을 천천히 늘릴 수도 있고 아니면 동적인 위젯을 몇 개 추가하는 것으로 끝낼 수도 있다.

 

react 공식 문서 링크 : https://ko.reactjs.org/docs/add-react-to-a-website.html

github 링크 : https://github.com/zerobase-school/2022-frontend-school-react/tree/master/2/2-1 

 

GitHub - zerobase-school/2022-frontend-school-react

Contribute to zerobase-school/2022-frontend-school-react development by creating an account on GitHub.

github.com

 

1단계: HTML 파일에 DOM 컨테이너 설치

먼저, 편집할 HTML 파일을 연다. 그 다음 비어있는 <div> 태그를 추가한다. 이 태그가 바로 React를 통해 원하는 내용을 표시할 수 있는 위치가 된다. 코드는 다음과 같다.

<!-- ... existing HTML ... -->

<div id="like_button_container"></div>

<!-- ... existing HTML ... -->

 <div> 태그에 유일한 HTML 속성인 id를 부여해준다. 이를 통해 JavaScript가 태그를 찾고 찾은 태그 안에 React 컴포넌트를 표시할 수 있게 된다.

 

2단계: 스크립트 태그 추가하기

그 다음, <script> 태그 3개를 닫는 태그인 </body> 앞에 추가한다.

  <!-- ... 다른 HTML ... -->

  <!-- React를 실행. -->
  <!-- 주의: 사이트를 배포할 때는 "development.js"를 "production.min.js"로 대체하세요. -->
  <script src="https://unpkg.com/react@17/umd/react.development.js" crossorigin></script>  
  <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
  <!-- 만든 React 컴포넌트를 실행. -->
  <script src="like_button.js"></script>
</body>

처음 두 태그는 React를 실행시키고 3번 째 코드는 만든 컴포넌트를 실행시킨다.

 

3단계: React 컴포넌트 만들기

like_button.js 라는 이름으로 HTML 페이지 옆에 새 파일을 만든다.

 스타터 코드 를 열고 코드를 방금 만든 파일에 복사한다.

 

like_button.js의 맨 뒷 줄, 그러니까 아까 붙여넣은 스타터 코드 뒤에 다음 코드 두 줄을 추가한다.

이 강의 스타터 코드는 예제로 제공되었다.

// ... 복사했던 스타터 코드 ...

const domContainer = document.querySelector('#like_button_container');
ReactDOM.render(e(LikeButton), domContainer);

이 두줄의 코드는 첫 단계에서 HTML 페이지에 추가했던 <div> 태그를 찾아주고 그 안에 “좋아요” 버튼이라는 React 컴포넌트를 추가한다.

 

끝!

다음 단계는 없다. 방금 웹사이트에 처음으로 React 컴포넌트를 추가했다.

 

우리가 한 일

1단계 : HTML 파일에 DOM 컨테이너 설치

2단계 : script 태그 추가하기

3단계 : React 컴포넌트 만들기

React를 사용해서 DOM element를 만들었고, HTML에 포함시켰다! 

 

어떤 element들 + 그 element들을 꾸미기 위한 style + 그 element의 동작에 대한 script를 묶기

우리가 만든 FollowButton이 하나의 "컴포넌트" !!

 

 

React.createElement() 함수에 대해서 더 알아보기

const element = document.createElement(tagName[, options])

➡ 지정한 tagName의 HTML 요소를 만들어서 반환

const element = React.createElement(component, props, ...children)

ReactElement 를 반환

 

const element = React.createElement(componentprops, ...children)

 

문자열 또는 리액트 컴포넌트

- 문자열일 때는 HTML 태그를 의미 ex) "div"

- 리액트 컴포넌트 ex) <FollowingButton />

 

component가 가질 수 있는 옵션들

- ex) style, className...

 

component가 감싸고 있는 내부 컴포넌트

- ex) "following" 등의 텍스트

- 리액트 컴포넌트 ex) <FollowingButton />

- ex) React.createElement("p", null, "hello")

 

 

ReactDOM.render() 함수에 대해서 더 알아보기

ReactElement를 루트의 DOM 노드에 렌더링 하기 위해서 사용

ReactDOM은 React 엘리먼트와 일치하도록 DOM을 업데이트 한다.

가상 DOM과 같이 생각하자.

 

공식 문서 링크 : https://ko.reactjs.org/docs/rendering-elements.html 

 

엘리먼트 렌더링 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

CRA

create-react-app으로 새로운 React앱 만들기

공식 문서 링크 : https://ko.reactjs.org/docs/getting-started.html 

 

시작하기 – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

추천 툴체인

React를 배우고 있거나 아니면 새로운 싱글 페이지 앱을 만들고 싶다면 Create React App.

서버 렌더링 Node.js 웹사이트를 만들고 있다면 Next.js

고정적인 콘텐츠 지향적 웹사이트를 만들고 있다면 Gatsby

컴포넌트 라이브러리 혹은 이미 있는 코드 베이스에 통합을 한다면 더 유연한 툴체인.

 

우리는 React를 배우고 있기 때문에 Create React App을 사용해보자!

 

Create React App

Node 14.0.0 혹은 상위 버전 및 npm 5.6 혹은 상위 버전이 필요하다.

새로운 프로젝트를 만들기 위해 아래의 명령어를 실행한다.

npx create-react-app my-app
cd my-app
npm start

 

react, react-dom 세팅하기

create-react-app(CRA) 없이 새로운 리액트 앱 만들기

React 앱을 만들기 위해 필수적인 개발 도구들

: Babel, Webpack, HMR(hot-module-replacement)...

 

각 도구들에 대해 알아보자.

 

Babel

공식 문서 링크 : https://babeljs.io/docs/en/index.html 

 

Babel · The compiler for next generation JavaScript

The compiler for next generation JavaScript

babeljs.io

Babel은 JavaScript 컴파일러이다.

ES6 JavaScript를 ES5로 변환을 해주는 역할을 한다.

 

JSX and React

Babel은 JSX 문법도 변환이 가능하다.

JSX : 리액트를 사용하기 위한 문법. JavaScript의 표준이 아니기 때문에 브라우저가 JSX를 읽을 수 있도록 변환이 필요하다.

@babel/preset-react

preset이란? 

react를 트랜스파일링 하기 위해 모아둔 세팅 모음집

 

 

react, react-dom, Babel 설정

우리의 목표 : Babel이 JSX ➡ JavaScript로 트랜스파일링 해주는 것을 직접 확인해보자

 

터미널 명령어 : mkdir ~ 

~ 라는 이름을 가진 새로운 폴더를 생성한다.

 

withoutCRA 폴더를 생성

npm init을 이용해 폴더를 초기화

npm install react react-dom을 이용해 react와 react-dom 설치

디렉터리 구조는 CRA와 동일하게 생성

 

Babel 세팅하기

npm i -D @babel/core @babel/cli @babel/preset-react

3가지의 패키지를 다운로드 한다.

@babel/preset-react

: 리액트와 관련된 코드를 컴파일하는 패키지

@babel/preset-env

: 모든 es6 plugin을 설치하는 패키지. 원하는 브라우저만 지원가능하도록 plugin을 선택할 수 있다.

@babel/cli

: 터미널에서 명령을 통해 babel 적용시킬 수 있도록 도와주는 패키지

@babel/core

: babel을 사용하기 위해 필수적인 패키지

명령어에 -D를 붙였기 때문에, package.json에 devDependencies에 추가되고, -D를 붙이지 않으면 Dependencies에 추가된다.

 

컴파일 시, babel ~~ 뒤에 일일이 적는 것이 번거롭기 때문에 

babel.config.js 파일을 생성하여 babel 명령어 하나로 컴파일 할 수 있도록 한다.

공식 문서 링크 : https://babeljs.io/docs/en/configuration

 

Babel · The compiler for next generation JavaScript

The compiler for next generation JavaScript

babeljs.io

babel.config.js 은 프로젝트의 root에 위치해야 한다.

config 파일은 json과 js 형식 두 가지로 표현할 수 있다. 

우리는 js 형식을 사용하여 구현한다.

module.exports = function (api) {
  api.cache(true);

  const presets = [ ... ];
  const plugins = [ ... ];

  return {
    presets,
    plugins
  };
}

presets = [] 안에 설치한 preset을 적는다.

ex) const presets = ["@babel/preset-env", "@babel/preset-react"];

plugins = [] 안에 설치한 plugin을 적는다.

구글에 babel plugin 검색 한 후 원하는 플러그인을 설치한다.

현재는 필요한 플러그인이 없기 때문에 생략한다.

 

Webpack 세팅하기

babel이 컴파일러라면, Webpack번들러이다.

공식 문서 링크 : https://webpack.js.org/ 

 

webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

번들러(Bundler)

: 분리된 JavaScript와 CSS 모듈 코드를 브라우저에 최적화된 여러 개의 파일로 결합한다. React 애플리케이션에서 널리 사용되는 번들러에는 Webpack과 Browserify가 있다.

번들러

 

싱글 페이지 애플리케이션(Single-page application, SPA)

: 하나의 HTML 페이지와 애플리케이션 실행에 필요한 JavaScript와 CSS 같은 모든 자산을 로드하는 애플리케이션이다. 페이지 또는 후속 페이지의 상호작용은 서버로부터 새로운 페이지를 불러오지 않으므로 페이지가 다시 로드되지 않는다.

여러 개의 js 파일을 하나의 js 파일로 만들어준다.

더보기

React를 사용하여 싱글 페이지 애플리케이션을 만들 수 있지만, 필수 사항은 아니다. 기존 웹 사이트 일부분의 상호작용을 개선하기 위하여 React를 사용할 수 있다. React로 작성된 코드는 PHP와 같은 서버에 의해 렌더된 마크업 또는 다른 클라이언트사이드 라이브러리와 함께 문제 없이 공존할 수 있다. 사실, Facebook에서는 위와 같은 방식으로 React를 사용하고 있다.

 

babel을 사용했던 것처럼 webpack에 대한 webpack.config.js 파일을 생성하여 한경설정을 한다.

config.js 안에 filename의 값을 html에 <script>로 설정한다.

 

먼저, npm i -D webpack webpack-cli html-webpack-plugin babel-loader 을 이용하여 webpack에 관련된 패키지를 설치한다.

webpack.config.js 파일을 생성해 js 형식으로 초기화한다.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "development",

  entry: "./src/index.js",

  module: {
    rules: [{ test: /\.js$/, use: "babel-loader" }],
  },

  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],

  optimization: { minimizer: [] },

  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
};

노드 모듈 중 path를 가져와서 파일들을 잘 읽을 수 있도록 처리한다.

 

mode는 아직 개발 단계이기 때문에 development라고 설정한다.

 

entry에는 src/index.js로 설정한다. js 파일이 index.js 로 시작하여 엮여져 있기 때문이다.

번들링을 한 파일을 어떤 위치에 만들 것인지 설정해야 한다

path: path.resolve(___dirname, "dist"는 "dist"라는 새로운 폴더 안에 결과가 만들어진다.

output된 파일 이름도 지정할 수 있다. 여기서는 "bundle.js"로 설정한다.

 

번들링을 하며 적용할 수 있는 rule을 추가할 수 있다.

위의 test 는 모든 js 파일을 읽을 때 babel-loader를 사용하겠다는 의미이다.

babel-loader의 역할 : Webpack이 파일을 불러들일 때 JSX 을 읽지 못한다. 그렇기 때문에 번들링을 하는 과정에서 babel설정을 실행할 수 있게 한다.

 

Webpack은 기본적으로 JavaScript 파일을 압축하게 되어있다. 

하지만 우리는 babel-loader가 제대로 동작하는지 확인해야 하기 때문에 압축 기능을 잠시 끈다.

 

 

html-webpack-plugin 

: 우리가 만든 결과물, bundle.js 을 index.html에 적용해서 새로운 html, 최종 html을 만들엊주는 역할

이 세팅도 원활한 개발 환경을 위해 추가하자.

bundle.js를 public에 index.html 에 자동으로 붙인 다음에 최종 html 파일을 dist 폴더에 같이 만들어주는 역할을 한다.

 

 

HMR(hot-module-replacement) 세팅하기

코드를 수정하고 확인하고 싶을 때 webpack을 실행하여 번들링을 한 후 확인을 할 수 있었다.

이런 방법은 효율적이지 않아!

➡ HMR(hot-module-replacement)를 적용하면 해결!

 

HMR(hot-module-replacement)

공식 문서 링크 : https://webpack.kr/guides/hot-module-replacement/ 

 

Hot Module Replacement | 웹팩

웹팩은 모듈 번들러입니다. 주요 목적은 브라우저에서 사용할 수 있도록 JavaScript 파일을 번들로 묶는 것이지만, 리소스나 애셋을 변환하고 번들링 또는 패키징할 수도 있습니다.

webpack.kr

HMR(hot-module-replacement)은 Webpack에서 제공하는 가장 유용한 기능 중 하나이다.

모든 종류의 모듈을 새로고침 할 필요 없이 런타임에 업데이트 할 수 있다. 

webpack-dev.server 설정을 업데이트 하고 webpack의 내장 HMR 플러그인을 사용하면 된다.

 

npm install -D webpack-dev-server 를 터미널에 입력하여 설치한다.

webpack.config.js에 들어가서 module.exports =  {} 안에 아래의 새로운 코드를 추가한다.

  devServer: {
    static: "./dist",
    hot: true, 
  },

dist를 update할 때마다 런타임으로 업데이트를 하는 명령이 실행된다.

 

위의 설정을 마쳤다면 HMR(hot-module-replacement)은 성공적으로 동작할 것이다.

'React' 카테고리의 다른 글

[React] 리스트와 key / 폼과 이벤트 제어하기  (0) 2022.07.26
[React] Lifecycle와 useEffect()  (0) 2022.07.25
[React] State  (0) 2022.07.09
리액트 기본 문법(JSX)과 컴포넌트 소개  (0) 2022.07.01
React 이론  (0) 2022.06.30