[React] CRA 없이 개발 환경 설정하기

unhyif·2022년 5월 12일
0

React

목록 보기
1/4

create-react-app은 트랜스파일러/모듈 번들러 등 필요한 도구들을 자동으로 셋업해주기 때문에 편리하다. 하지만 사용하지 않는 도구들도 많이 내장되어 있고, 이러한 환경을 커스터마이징하기 어렵다는 단점이 있다.
그동안 무지성으로 CRA를 써왔기 때문에, 오늘은 CRA 없이 초간단한 react 앱을 만들어 보면서 react 앱이 필요로 하는 도구들에 대해 이해해 보고자 한다. 그러고 나면 CRA가 왜 편했는지 알게 될 것 같다 🙄

프로젝트 시작

폴더 하나를 만든 후, 루트 경로에 package.json을 생성한다.

npm init -y

패키지 설치

1. react/react-dom

npm install react react-dom

2. 모듈 번들러 webpack

모듈 번들러는 여러 유형의 파일들을 작은 파일 그룹으로 압축시키는 번들링을 한다.
번들링을 거치면 브라우저에 렌더링하기 위한 HTTP 요청 수가 감소하므로, 페이지 로딩이 빨라질 수 있다. 또한 올바른 순서로 모듈을 로딩하는 것에도 도움이 된다고 한다.

npm install webpack webpack-cli webpack-dev-server --save-dev

cf) --save-dev 옵션으로 설치하는 이유는, 프로덕션 빌드 시 webpack이 포함되지 않기 때문이다.

3. webpack 플러그인 html-webpack-plugin

번들링 결과물을 HTML 파일과 연결시켜주는 webpack 플러그인이다.

npm install html-webpack-plugin --save-dev

4. 트랜스파일러 babel

React는 최신 JS 문법을 사용하기를 권장하는데, 대부분의 브라우저들은 이를 이해하지 못한다. 따라서 브라우저가 이해할 수 있는 하위 버전 문법으로 변환시켜주는 트랜스파일러가 필요하다.

npm install @babel/core @babel/preset-env @babel/preset-react --save-dev
  • preset-env: ES6+ 버전 문법 -> ES5 이하 버전 문법으로 변환
  • preset-react: JSX 코드 -> JS 코드로 변환

5. 로더 babel-loader

로더는 webpack이 번들링 시 사용하는 도구로, 특정 유형의 파일을 처리하는 데에 사용된다.
따라서 프로젝트에서 쓰이는 파일 유형에 따라 로더들을 추가해야 한다. 예를 들어 CSS 파일이 있다면 css-loaderstyle-loader, SASS 파일이 있다면 sass-loader를 설치해야 한다.
지금 만들 react 앱은 JS 파일로만 구성될 것이므로, babel을 사용하는 babel-loader만을 설치한다.

npm install babel-loader --save-dev

-> 모두 설치를 완료하면 package.json은 아래처럼 보인다.

{
  "name": "without-cra",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.17.10",
    "@babel/preset-env": "^7.17.10",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.5",
    "html-webpack-plugin": "^5.5.0",
    "webpack": "^5.72.1",
    "webpack-cli": "^4.9.2",
    "webpack-dev-server": "^4.9.0"
  }
}

그리고 다음과 같이 폴더와 파일들을 만들어 주자.


Webpack 설정

// webpack.config.js

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

module.exports = {
  // 앱이 시작되는 지점
  entry: "./src/index.js",

  // 번들링 결과물의 저장 위치/파일명 설정
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "bundle.js",
  },

  // 번들링 결과물에 추가적인 기능을 실행하는 플러그인 등록
  plugins: [new HTMLWebpackPlugin({ template: "./public/index.html" })],

  // 여러 유형의 파일들 처리 방법 설정
  module: {
    rules: [
      {
        test: /.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: { presets: ["@babel/preset-env", "@babel/preset-react"] },
        },
      }, // babel을 사용하여 node_modules 폴더 내 파일들을 제외한 모든 js 파일을 트랜스파일링
    ],
  },
};

https://webpack.kr/configuration/ 에 자세한 내용이 있다.


그리고 파일마다 아래 코드를 작성한다.

<!-- public > index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>
// src > index.js

import React from "react";
import { createRoot } from "react-dom/client";
import App from "./components/App";

const root = createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
// src > components > App.js

import React, { Component } from "react";

export default class App extends Component {
  render() {
    return <h1>Hello world!</h1>;
  }
}

앱 실행

앱을 webpack-dev-server에 띄울 것이다. 그를 위한 npm 스크립트를 만들어 보자.
package.json"scripts" 부분을 다음과 같이 수정한다.

  "scripts": {
    "start": "webpack-dev-server --mode development --open --hot"
  },

개발 모드로 앱을 실행하며, 새 창이 열리도록 할 것이고 변경 사항을 실시간으로 서버에 반영하겠다는 의미이다.

npm start

를 입력하면, 성공적으로 앱이 실행된다!

앱 빌드

package.json"scripts" 부분에 "build" 명령어를 추가해 준다.

  "scripts": {
    "start": "webpack-dev-server --mode development --open --hot",
    "build": "webpack --mode production"
  },
npm run build

를 입력하면

webpack.config.js에서 설정해 준대로 dist 폴더에 번들링 결과물 bundle.js 가 생성됐고, index.html 를 확인해 보면 bundle.js가 연결되어 있다.

<script defer="defer" src="bundle.js"></script>

TIL

아직 webpack과 babel에 대해 상세히 알진 못한다. 하지만 webpack <-> babel 관계와 더불어 프로덕션 빌드가 어떻게 생성되는지, 그리고 앱을 띄울 수 있는 서버가 여러 가지라는 것을 알 수 있었다! react 개발 환경을 직접 설정하는 데에 있어서 레벨 0 -> 1로 진급한 느낌이다.. 🥳
프로젝트가 복잡해지면 환경 설정의 난이도가 높아질 것 같은데, CRA 한 줄이 얼마나 편한 것이었는지 체감할 수 있었다.
틀린 내용이 있다면 알려주세요!


Reference: https://www.youtube.com/watch?v=h3LpsM42s5o&t=722s
https://wittcode.com/javascript/create-a-react-app-without-using-create-react-app
https://medium.com/@JedaiSaboteur/creating-a-react-app-from-scratch-f3c693b84658

0개의 댓글