React 개발환경 구축

BHwi·2022년 7월 21일
0

React 개발환경 구축

  1. React 기본 설정
  2. Babel
  3. Webpack

1. React 기본 설정

React의 특징

React는 가상 돔을 통해서 UI를 빠르게 업데이트하는 장점을 가져 우수한 성능을 보이는 라이브러리이다.
React는 함수형 프로그래밍을 적극 활용하며 다음과 같은 조건을 지키는 것을 권장한다.

  1. render 함수는 순수 함수로 작성한다.
  2. state는 불변 변수로 관리한다.

render 함수는 순수함수여야하므로 인수 state가 변하지 않으면 항상 같은 값을 반환해야한다.
또, 컴포넌트의 상탯값을 수정할 때는 기존 값을 변경하는 것이 아닌 새로운 객체를 생성해야한다.

이를 사용하는 이유는 코드의 복잡도가 낮아지고, 찾기 힘든 버그가 발생할 확률이 줄어들기 때문이다.
무엇보다도 이 두 조건을 만족하면 렌더링 성능을 크게 향상 시킬 수 있다.

개발 환경 구축하기

다음 링크를 통해 React javascript 파일 4개를 내려받는다.

https://unpkg.com/react@16/umd/react.development.js
https://unpkg.com/react@16/umd/react.production.min.js
https://unpkg.com/react-dom@16/umd/react-dom.development.js
https://unpkg.com/react-dom@16/umd/react-dom.production.min.js

Hello World 페이지 구현

Directory 만들기

위에서 받은 파일 4개를 활용하여 구현할 페이지 폴더를 만든다.
hello-world directory 구성은 다음과 같다.

hello-world
⊢react.development.js
⊢react.production.min.js
⊢react-dom.development.js
⊢react-dom.production.min.js
⊢simple1.html
⊢simple1.js

코드 작성

기본적으로 html 파일에는 id가 root 혹은 react-root 인 div 태그를 추가한다.
js 파일에서 html에 함수를 통해 추가하는 방식이기 때문이다.

<html>
  <body>
    <h2>Hello. Push the 'Like' Button</h2>
    <div id="react-root"></div>
    <script src="react.development.js"></script>
    <script src="react-dom.development.js"></script>
    <script src="simple1.js"></script>
  </body>
</html>

JS 파일에는 간단한 버튼을 추가한 형태로 구성한다.

function LikeButton() {
  const [liked, setLiked] = React.useState(false);
  const text = liked ? "Like cancel" : "Like";

  return React.createElement(
    "button",
    { onClick: () => setLiked(!liked) },
    text
  );
}

const domContainer = document.querySelector("#react-root");
ReactDOM.render(React.createElement(LikeButton), domContainer);

React.useState 함수는 변수와 변수를 수정하는 함수를 만들어준다.
각각 const [변수, 변수에 대한 함수]로 구성되며 보통의 경우는 함수 이름은 set + '변수'로 설정한다.
liked 변수를 사용하는 text 변수는 liked 값이 변경될 때마다 값이 변경되도록 설정된다.
그 후 React.createElement 함수를 통해 React 요소를 반환한다.(최종적으로 돔 요소가 된다.)

위 HTML 파일에서 선언한 react-root div를 querySelector를 통해 가져온 후, ReactDOM의 render 함수를 통해 랜더링을 수행한다.

CreateElement의 구성

첫 번째 매개변수 component는 일반적으로 문자열, react component이다. component 변수가 문자열인 경우 HTML 태그에 해당하는 돔 요소를 생성한다.

두 번째 매개변수 props는 component가 사용하는 데이터를 나타낸다. 돔 요소의 경우 style, className 등이 포함된다.

세 번째 매개변수 children은 해당 컴포넌트가 감싸고 있는 내부의 컴포넌트를 가리킨다.

다음은 같은 구성의 코드를 HTML과 createElement로 나타낼 경우이다.

<div>
  <p>hello</p>
  <p>world</p>
</div>
React.createElement(
  'div',
  null,
  createElement('p', null, 'hello'),
  createElement('p', null, 'world')
)

CreateElement 함수가 복잡하므로 대부분의 개발자들은 Babel을 사용한 JSX 문법을 사용한다. JSX 문법은 가독성 면에서 훌륭하다. 게시물을 참고하면서 자세히 알아보자.
https://goddaehee.tistory.com/296

2. Babel

Babel의 필요성

React에서 매번 createElement를 사용하는 것은 굉장히 비효율적이다.
그래서 JSX를 사용하는데, 일반 HTML에서는 이를 인식하지 못한다. 따라서 그에 대한 번역기가 필요하고, Babel은 그 번역기 역할을 수행한다.

코드 작성

코드 작성 전, JS 파일은 hello-world 폴더 내에 src 폴더를 만들어 내부에 저장한다.

<html>
  <body>
    <h2>Hello. Push the 'Like' Button</h2>
    <div id="react-root"></div>
    <script src="react.development.js"></script>
    <script src="react-dom.development.js"></script>
    <script src="simple2.js"></script>
  </body>
</html>
...
function Container() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <LikeButton />
      <div style={{ marginTop: 20 }}>
        <span>count : </span>
        <span>{count}</span>
        <button onClick={() => setCount(count + 1)}>increase</button>
        <button onClick={() => setCount(count - 1)}>decrease</button>
      </div>
    </div>
  );
}

const domContainer = document.querySelector("#react-root");
ReactDOM.render(React.createElement(Container), domContainer);

위와 같이 코드를 작성한 후 설치된 패키지를 이용하여 파일을 변환한다.

npx babel --watch src --out-dir . --presets @babel/preset-react

파일이 정상적으로 번역됨을 확인할 수 있다. 번역된 결과는 hello-world 폴더에 저장된다.

function LikeButton() {
  const [liked, setLiked] = React.useState(false);
  const text = liked ? "Like cancel" : "Like";
  return React.createElement("button", {
    onClick: () => setLiked(!liked)
  }, text);
}

function Container() {
  const [count, setCount] = React.useState(0);
  return /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(LikeButton, null), /*#__PURE__*/React.createElement("div", {
    style: {
      marginTop: 20
    }
  }, /*#__PURE__*/React.createElement("span", null, "count : "), /*#__PURE__*/React.createElement("span", null, count), /*#__PURE__*/React.createElement("button", {
    onClick: () => setCount(count + 1)
  }, "increase"), /*#__PURE__*/React.createElement("button", {
    onClick: () => setCount(count - 1)
  }, "decrease")));
}

const domContainer = document.querySelector("#react-root");
ReactDOM.render(React.createElement(Container), domContainer);

3. Webpack

Webpack의 기본 개념

인터넷이 발전하면서, 사이트에서 사용되는 자바스크립트의 파일이 많아졌다. 이 때문에 파일 간의 의존성이 부합하지 않는 문제가 생기거나, 앞서 선언한 전역변수를 덮어쓰는 위험도 존재하여 파일을 묶어 관리하는 것이 중요해졌다.
이 때문에 프로그램을 배포하기 좋은 형태로 묶어주는 도구인 Webpack을 사용하기 시작했다.

ESM 문법

자바에서 import 문을 사용하여 외부 라이브러리를 불러오는 기술이라고 생각하면 쉽다.

// file1.js
export default function func1() {}
export function func2() {}
export const variable1 = 123;
export let variable2 = 'hello';

// file2.js
import myFunc1, {func2, variable1, variable2 } from './file1.js';

// file3.js
import { func2 as myFunc2 } from './file1.js';

export, import from

코드를 내보낼 때는 export 키워드를 사용하고, 코드를 사용할 때는 import, from 키워드를 사용한다.

default 키워드

default 키워드는 한 파일에서 한 번만 사용할 수 있고, 내보내진 코드는 괄호없이 가져올 수 있고, 이름은 원하는 대로 정할 수 있다.
위에서 file1.js의 func1 함수는 file2에서 myFunc1 이라는 이름의 함수로 불러온 것이다.
default 키워드가 없는 경우는 괄호를 사용하여 가져온다. 가져올 때는 내보낼 때 사용된 이름을 그대로 가져와야하지만, 다른 이름으로 사용하고 싶은 경우 as 키워드를 사용한다.

webpack-test

위에서 배운 webpack을 사용해보자.
먼저 webpack-test 폴더를 만들어 해당 폴더에서 npm init -y 명령어를 입력하면 package.js 파일이 만들어진다.

기존에 사용한 html, js 파일들을 조금 수정하여 사용할 예정이다. react, react-dom 스크립트 부분을 삭제하고, js 파일 스크립트 부분을 ./dist/main.js로 수정한다.
dist/main.js에는 src에서 작성한 index.js를 토대로 이것이 webpack을 통해 합쳐질 것이다.

다음과 같은 폴더를 생성하여, src 폴더에 index.js, Button.js를 추가한다.

모든 파일이 준비되었다면 아래 명령어를 입력하여 외부 패키지들을 설치한다.
npm install webpack webpack-cli react react-dom

webpack-test 코드

// index.html
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <h2>Hello. Push the 'Like' Button</h2>
    <div id="react-root"></div>
    <script src="./dist/main.js"></script>
  </body>
</html>
// index.js
import React from "react";
import ReactDOM from "react-dom";
import Button from "./Button.js";

function Container() {
  return React.createElement(
    "div",
    null,
    React.createElement("p", null, "버튼을 클릭해 주세요."),
    React.createElement(Button, { label: "좋아요" }),
    React.createElement(Button, { label: "싫어요" })
  );
}

const domContainer = document.querySelector("#react-root");
ReactDOM.render(React.createElement(Container), domContainer);
// Button.js
import React from "react";

export default function Button(props) {
  return React.createElement("button", null, props.label);
}

작성한 코드들을 이제 웹팩을 이용하여 하나의 파일로 합쳐보자.

npx webpack

위와 같이 나온다면 webpack으로 묶는 것에 성공한 것이다.

결과물

0개의 댓글