노마드코더

[ReactJS로 영화 웹 서비스 만들기] 4. Create React App

졸려질려 2023. 4. 27. 12:49
반응형

 본 글은 노마드코더의 "ReactJS로 영화 웹 서비스 만들기" 강의를 정리한 글입니다. 더 자세한 내용과 설명은 무료 강의를 들어주세요!

 

ReactJS로 영화 웹 서비스 만들기 – 노마드 코더 Nomad Coders

왕초보를 위한 React

nomadcoders.co

 지난 글에서는 ReactJS 의 Props 에 대해 정리하였다.

 

[ReactJS로 영화 웹 서비스 만들기] 3. Props & PropTypes

ReactJS로 영화 웹 서비스 만들기 – 노마드 코더 Nomad Coders 왕초보를 위한 React 본 글은 노마드코더의 "ReactJS로 영화 웹 서비스 만들기" 강의를 수강하고, 개인적으로 정리한 글입니다. 더 자세하고

choboit.tistory.com

 이번에는 간단히 React App 을 만드는 방법에 대한 강의를 듣고 정리하고자 한다.


 이번 강의에서 다루는 것은 "create-react-app" 에 관한 것이다. create-react-app 은 평범한 영어 문장 같지만, React App 을 만들 수 있게 해주는 라이브러리의 이름 그 자체이다.

create-react-app Github 페이지 일부

 CRA 를 사용하기에 앞서서 Node 와 npx 가 실행되는 환경을 구축해줘야한다. npx 는 Node 를 설치하면 같이 실행되는 것이므로 Node 만 설치해주면 된다. Node 설치 방법은 공식 문서나 다른 블로그에서도 많이 정리되어 있으니 본 글에서 생략한다. Node 설치는 공식 홈페이지를 통해 설치할 수 있다.

 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

 Node 설치가 완료되면 다음 두 명령어를 통해 잘 설치되었는지 확인할 수 있다.

// Node Version
node -v

// NPX
npx

 위 사진과 같이 정상적으로 실행된다면, Node 환경 구축은 마친 것이다.


1. React 앱 프로젝트 생성

 이제 CRA(Create-React-App) 를 사용하여 앱 프로젝트 폴더를 생성할 것이다. 명령어는 다음과 같다.

npx create-react-app [PROJECT_NAME]

 "npx create-react-app" 명령어 뒤에 원하는 프로젝트(폴더) 이름을 추가해주면 된다. 프로젝트 이름에 대문자가 들어가면 생성이 되지 않으니 소문자로만 구성하여 명령어를 실행한다.

FirstReactApp 이 아닌 first-react-app

 설치가 완료되면 명령어를 실행했던 위치에 앱 프로젝트 폴더가 생성되어 있을 것이다.

생성된 React 앱 프로젝트 폴더


2. React App 실행

 현재 생성된 프로젝트는 CRA 에서 만들어준 기본적인 템플릿 형태이며, 앱을 실행하면 간단하게 화면이 구성되어 있다. "package.json" 파일을 살펴보면 앱을 실행할 수 있는 명령어를 알 수 있다.

 위 사진에 나온 "scripts" 중에서 "start" 를 사용하면 현재 구성된 React App 을 실행할 수 있다. 명령어는 다음과 같다.

npm run start

 위 명령어는 실행하고자 하는 React App 의 프로젝트 위치에서 명령어를 실행 해야한다. 실수로 상위 폴더에서 실행한다면 엉뚱한 앱이 실행되거나, 오류로 인해 실행이 안될 수 있다.

 명령어를 실행하면 위와 같이 결과 메시지가 출력되고, 자동으로 브라우저에 페이지 하나가 열릴 것이다. 그것이 바로 현재 프로젝트에서 구현된 React App 의 모습이다.

자동으로 열리는 React App 페이지

 웹페이지는 기본적으로 "index.html" 과 "index.js" 가 필수적으로 존재한다. 현재 React 프로젝트에서 "index.html" 은 public 폴더에 있고, "index.js" 는 src 폴더에 존재한다. "index.js" 파일을 보면 정말 간단하게 코드가 구성되어 있다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

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

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 위 코드는 이전 강의를 정리하면서 보았던 코드와 유사한 것이 많다. 이전 강의에서는 위 코드를 index.html 의 위치에 같이 두었지만, 여기서는 분리되어 존재하고 있다. 그 안에서도 <React.StrictMode> 안에 있는 <App /> 이 있는 것을 확인할 수 있다. <React.StrictMode> 은 나중에 정리할 것이다. <App /> 은 import 를 통해 사용한 것이며, 이전 강의에서 계속 만들어보았던 Component 의 모습이다. <App /> 의 내부 코드는 src 폴더에 있는 "App.js" 파일에서 확인할 수 있다.

import logo from './logo.svg';
import './App.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;

 "App.js" 파일은 위와 같이 구성되어 있다. JSX 로 하나의 Component 를 구현하였다. 그리고 처음에 React App 을 브라우저에 띄웠을 때 나왔던 화면의 모습이기도 하다. 위 코드에서 <p> 에 있는 값을 변경하면 브라우저에 나타난 페이지가 위 코드임을 알 수 있다.

...
    <p>
      Hello <code>src/App.js</code> and save to reload.
    </p>
...

 Edit 을 Hello 로 수정하고 저장하면 Auto Reload 가 되어서 브라우저에 바로 적용되는 것을 확인할 수 있다. 여기서 CRA 의 장점인 "Auto Reload" 를 같이 확인할 수 있다.


3. 불필요 코드 제거

 정확히는 현재 니코쌤의 강의에 따라 불필요한 코드를 제거하는 것이다. "index.js" 파일에서는 아래 코드와 같이 간소화 시켜준다.

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

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

 이어서, "App.js" 파일도 다음과 같이 간소화 시켜준다.

function App() {
  return (
    <div>
      <h1>Welcome Back!</h1>
    </div>
  );
}

export default App;

 그리고 마지막으로 src 폴더 안에 파일을 정리해준다. "App.js" 와 "index.js" 파일만 두고, 나머지 파일들을 모두 삭제한다.

 이제 강의에 맞는 프로젝트 모습으로 만들어졌다.


4. CRA 간단 사용 - Dependency

 우선, "Button.js" 파일을 생성하여 간단한 컴포넌트를 만들어준다.

// Button.js

function Button({text}) {
    return <button>{text}</button>
}

export default Button;

 보다시피 Props 가 적용되어 있다. 이제 Button 을 App.js 에 추가하여준다.

// App.js

import Button from './Button';

function App() {
  return (
    <div>
      <h1>Welcome Back!</h1>
      <Button text={"Continue"}/>
    </div>
  );
}

export default App;

결과 화면

 Prop 이 있으니 이번에는 "PropTypes" 를 사용해보자. "PropTypes" 는 이전에 unpkg 경로를 <script> 에 넣어서 사용했다. 하지만, 지금은 HTML 파일 하나에서 코드를 다 짜는 것이 아니다. 지금 같이 Node 로 프로젝트가 생성되었을 경우, NPM 을 통해 필요한 라이브러리를 다운 받는다. 이전에도 PropTypes 를 사용할 때, NPM 페이지에서 unpkg 경로를 찾았다. 즉, NPM 을 통해 동일한 PropTypes 를 설치할 수 있다. 방법은 간단하다. 프로젝트 위치에서 다음 명령어를 통해 PropTypes 를 설치한다.

NPM - PropTypes 문서 중 일부

 설치가 완료되면, "package.json" 파일에서 "dependencies" 블럭 안에 "prop-types" 가 추가된 것을 확인할 수 있다. 위 명령어에서 버전을 따로 적지 않았기 때문에, 가장 최신 버전으로 설치되었다.

 라이브러리를 설치했으니, "PropTypes" 를 "Button.js" 에서 사용해 볼 것이다. 라이브러리를 사용할 때는 코드의 최상단에 import 구문으로 필요한 라이브러리를 추가해준다.

import PropTypes from "prop-types";

 CRA 에서 위와 같이 import 를 해주면, 그에 맞는 자동완성 기능도 활성화가 된다.

 자동완성 기능은 그 유무에 따라 작업 속도가 천차만별로 차이가 나기 때문에 정말 유용하다. 이제 PropTypes 로 Button 의 text 에 String 을 필수로 넣도록 조건을 명시한다.

// Button.js

import PropTypes from "prop-types";

Button.propTypes = {
    text: PropTypes.string.isRequired
}

function Button({text}) {
    return <button>{text}</button>
}

export default Button;

 이제 Button 에 String 이 아닌 다른 값을 넣어서 조건이 잘 작동하고 있는지 확인한다.

 Button 의 text 속성에 number 형으로 123 을 넣었더니 렌더링은 됐지만 오류가 출력되었다. PropTypes 가 적용되었다는 의미이기도 하다. 이제 마지막으로 CRA 에서 CSS Module 을 사용해본다.


5. CRA 간단 사용 - CSS Module

 이전에 CSS 는 HTML element 의 속성인 id 나 class 의 이름을 통해 CSS 에서 설정하는 방식이었다. 이번에 배운 CSS Module 은 반대로 CSS 파일의 값을 React 코드 단에서 객체처럼 사용할 수 있게 해준다.

 사용법은 간단하다. 우선, 이전에 만든 Button.js 의 이름에서 "Button" 만 똑같이 복사하고, 뒤에 ".module.css" 를 붙여서 파일을 만들어준다.

 이제 "Button.module.css" 파일 안에 간단하게 CSS 를 작성해준다.

.btn {
    border-radius: 20px;
    background-color: tomato;
    color: white;
    font-size: 24px;
}

 그 후, "Button.js" 파일로 돌아와서, 방금 만든 "Button.module.css" 를 import 시켜준다.

// Button.js

import styles from './Button.module.css';

 이제 "Button.module.css" 파일은 "Button.js" 파일 내에서 "styles" 라는 이름으로 참조할 수 있다. 이제 <button> 안에 "className" 속성을 통해 ".btn" 을 넣어준다.

// Button.js

import styles from './Button.module.css';

...

function Button({text}) {
    return <button className={styles.btn} >{text}</button>
}

 저장을 하고 Reload 된 페이지를 보면 다음과 같이 적용된 것을 볼 수 있다.

 이처럼 CSS 의 내용을 객체처럼 참조하여 사용할 수 있게 되었다. 원래라면 <button> 에 id 나 class 이름을 정해주고, 해당 이름에 맞는 CSS 값을 설정해야 됐다. 그런데 CSS Module 기법을 사용하면, <button> 에 id 나 class 이름을 정해줄 필요 없이, CSS 에서 먼저 디자인에 맞는 값을 설정해두면 다른 element 가 추가되더라도 비슷한 CSS 값을 원할 때 재사용하기 쉬워진다.

 위의 상태로 Inspect 창에서 화면의 구성요소를 살펴보면 다음과 같이 나타난다.

 코드 상에서는 <button> 의 className 에 CSS 에 대한 참조값을 넣었지만, 실제 페이지에서는 임의의 class 값이 입력되어있다.

반응형