본문 바로가기
React Study

CRA(Create React App) 직접 구현하기 (2) - 구현

by KMS_99 2024. 5. 22.

<이전글> 바벨과 웹펙에 대하여

 

CRA(Create React App) 직접 구현하기 (1) - 바벨과 웹팩이란

CRA(Create React App)은 React App을 구현하기 위해 필요한 여러 보일러플레이트를 자동으로 설정해주는 도구이다.자동으로 설정되기 때문에 Webpack과 Babel의 지식이 없어도 개발을 진행할 수 있도록 도

audtjqxx.tistory.com

 

1. npm init

React App에서는 npm을 통한 모듈 의존성 관리를 한다. 따라서 npm init 이라는 명령어를 통해 의존성 관리를 도와주는 pakage.json 파일을 생성한다. (-y를 통해 빠르게 생성하자)

 

 

<결과>

 

위와 같이 package.json 파일이 자동생성된 것을 알 수 있다.

그렇다면 package.json은 무엇일까?

package.json은 개발자가 배포한 패키지에 대한 정보를 보여주며, npm을 통해 설치한 패키지를 사용하기 위한 명세를 담고 있다. 

 

위에 설정된 기본 필드에 대해서 알아보자.

name: 패키지 이름
version: 패키지 버전
description: 패키지에 대한 상세 설명 (npm에서 검색되었을 때 보여지는 설명)
main: 패키지의 진입점을 설정. package.json 파일이 읽히면 해당 진입점 파일 실행
scripts: 패키지 생명주기 내에서 command alias를 지정하여 명령어를 간편하게 실행하기 위함
keywords: npm에서 검색이 되기 위해 도움을 주는 keyword 
author: 배포자 (다수일 경우 contributors로 작성)
license: 배포한 패키지의 권한과 제한사항을 명시

2. 필요한 패키지 설치

리액트는 기본적으로 react와 react-dom으로 구성된다. 따라서 해당하는 패키지를 설치한다.

// yarn 기준, 블로그 포스팅 기준
yarn add react react-dom 

// npm 기준
npm install react react-dom

 

<결과>

 

결과를 보면 package.json에 dependencies라는 필드가 생성되어 방금 설치한 패키지 명과 버전이 명시됨을 알 수 있으며, 폴더 구조에 node_modules와 yarn.lock 파일이 생성됨을 알 수 있다.

 

 각 생성된 요소들에 대해서 알아 볼 필요가 있다.

 

- node_modules : package.json dependencies에 명시된 묘듈의 파일을 직접적으로 가지고 있는 폴더, npm registry로 부터 다운된다.

- yarn.lock : dependencies에 명시된 모듈들은 버전을 가지고 있다. 이 때 ^(틸드)와 같은 기호를 명시한다면, react 모듈 기준 18.3.1 이상 19.0.0 미만의 최신 버전을 설치하게된다. 즉, 모듈의 버전이 정확히 고정되지 않았다는 것이다. 따라서 lock파일을 만들어서 initializing 했을 때 버전을 고정한다. 결론적으로 yarn.lock은 버전을 고정하기 위한 파일이다. (npm 기준 package-lock.json)


3. 폴더 구조 세팅

 

기본적으로 cra를 했을 때 나오는 프로젝트 구조를 만들어야한다.

public 폴더와 src 폴더가 생성되었으며 그 역할은 다음과 같다.

 

- public : html 혹은 다른 정적 파일을 위한 폴더

- src : js나 jsx 파일이 들어가기 위한 폴더

 

public에는 index.html이 src에는 index.js가 위치하게된다.

index.html은 SPA 어플리케이션을 만드는 React에 유일하게 구성되는 html 파일이다. 따라서 해당 html에서 랜더작업이 이루어진다. src 내부의 index.js는 package.json에 명시된 진입점으로 index.html을 불러와서 작성, 변환된 js 파일을 실행시키도록 해주는 파일이다. 각 파일 내의 구조는 어떻게 구성될까?

 

- index.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <title>React App</title>
    </head>
    <body>
        <div id="root"></div>
    </body>
</html>

 

- 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>
);

 

index.js는 일반적인 html 파일 구조로 body에 root 라는 id를 가진 div가 생성되어있다.

해당 root는 index.js의 내용이 랜더되는 위치라고 할 수 있다. 

index.js의 코드를 보면 해당 id를 검색하여 루트로 지정한 것을 알 수 있으며, root.render()메서드를 통해 App이라는 컴포넌트를 랜더시키고 있다. 

(App 컴포넌트의 구성은 남은 설정을 마치고 진행 예정)


<check point!> React-eject란?

위 사진은 cra를 했을 때 생겨나는 파일들이다.

그런데 위 내용을 보았을 때 webpack이나 babel에 대한 설정은 어디를 봐도 찾을 수 없다.

cra는 webpack이나 babel과 같은 여러 주요 설정파일을 숨김처리하여 자동으로 관리해준다.

이를 숨김처리를 해제하고 확인할 수 있게해주는 것이 react-eject이다. 

다만 이 명령어를 사용하면 이전으로 되돌릴 수 없으며, 이후에는 여러 프로젝트 의존성과 설정 등을 사용자가 직접 관리(유지보수) 해야한다. 

다음과 같이 경고가 발생하니 eject시에는 조심하자

 

rject 결과

이제 우리가 확인하고 싶은 여러 설정파일을 확인할 수 있다. 이를 참고해서 webpack 먼저 직접 설정해보자.


4. 웹팩 및 바벨 설정

웹팩과 바벨을 프로젝트에 적용하기 위해 다음 의존성을 추가한다.

 

1. webpack 의존성

# webpack : 웹팩을 사용하기 위한 패키지
# webpack-cli : 웹팩의 명령어를 사용하기 위한 패키지
# webpack-dev-server : 웹팩에서 지원하는 개발서버를 이용하기 위한 패키지
# html-webpack-plugin : webpack 처리를 통해 html을 생성하고 관리하기 위한 패키지

# yarn
yarn add -D webpack webpack-cli webpack-dev-server html-webpack-plugin

# npm
npm install --save-dev webpack webpack-cli webpack-dev-server html-webpack-plugin

 

2. babel 의존성

# babel-loader : 웹팩과 바벨을 연동하기 위한 로더 패키지
# @babel/core : 바벨의 핵심 패키지
# @babel/preset-env : ES6+ 문법을 ES5 문법으로 변환하기 위한 바벨 패키지
# @babel/preset-react : JSX문법을 브라우저엔진이 인식할 수 있는 Javascript 문법으로 변환하기 위한 바벨 패키지

# yarn 
yarn add -D babel-loader @babel/core @babel/preset-env @babel/preset-react 

# npm
npm install --save-dev babel-loader @babel/core @babel/preset-env @babel/preset-react

 

 

 

의존성을 설치하였다면, 이제 루트에 webpack.config.js 파일을 생성하여 기본 세팅을 해보겠다.

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

module.exports = {
  // 번들링 시작 파일 (진입점)
  entry: "./src/index.js",
  output: {
    // webpack의 결과물이 저장되는 경로
    // __dirname은 현재 파일의 상위 폴더, 즉 root의 dist 폴더를 나타낸다
    // webpack의 결과는 /dist/bundle.js로 저장
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  module: {
    // 로더설정
    rules: [
      {
        // 로더를 적용할 파일 형식 (.js or .jsx)
        test: /\.(js|jsx)$/,
        // 무시할 디렉토리
        exclude: /node_modules/,
        // webpack과 babel 호환 설정 (babel을 이용한 jsx, es6+ 문법 호환)
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
  resolve: {
    // import 시 생략할 확장자 명
    extensions: [".js", ".jsx"],
  },
  //웹팩 플러그인 설정
  plugins: [
    new HtmlWebpackPlugin({
      // 번들링된 Javascript 파일을 index.html파일을 기반으로 합친 새로운 html 생성
      template: "./public/index.html",
    }),
  ],
  // 개발서버 설정
  devServer: {
    // 정적파일이 저장되는 (webpack 파일) 디렉토리 지정
    static: {
      directory: path.join(__dirname, "dist"),
    },
    // gzip 압축을 활성화하여 파일크기 최적화
    compress: true,
    // 개발서버 지정
    port: 3000,
  },
};

 

 

webpack 설정에 비해 babel 설정은 간단하다. 사용할 preset만 등록하면 된다.

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

5. 랜더 컴포넌트 구성

index.js를 구성할 때 App 컴포넌트를 미리 참조하였다.

이제 간단한 "Hello Wolrd"를 출력하는 컴포넌트를 제작해보겠다.

import React from "react";

const App = () => {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

export default App;

6. script 명령어 추가

실행을 위한 start와 빌드를 위한 build 명령어를 추가해야 결과를 확인할 수 있다.

webpack 설정에서 개발서버 설정도 추가했었을 것이다.

우리는 해당 개발서버를 이용하여 실시간으로 변경사항 확인을 확인할 수 있다.

package.json에 다음 script 명령어를 추가하자.

  "scripts": {
    "start": "webpack serve --mode development",
    "build": "webpack --mode production"
  },

7. 실행

이제 실행한 결과를 확인하자.

# npm
npm start

#yarn
yarn start

 

 

정상적으로 Hello wolrd가 출력되는 것을 확인할 수 있다.

 

물론 분명히 더 많은 설정이 CRA 환경에 포함되어있겠지만, 이렇게 기본적인 설정만으로 리액트 환경을 충분히 구현할 수 있다.

 

결론 : 이러한 복잡한 과정을 명령어 한줄에 설정해주는 CRA에 감사함을 느끼며 코딩에 집중하면 되겠다..!

 

소스코드 :

 

GitHub - kms99/Imprement_CRA: CRA 환경을 직접 구현하며, 웹팩/바벨에 대해 학습합니다.

CRA 환경을 직접 구현하며, 웹팩/바벨에 대해 학습합니다. Contribute to kms99/Imprement_CRA development by creating an account on GitHub.

github.com