[React] 템플릿 없이 개발 시작하기

invisibleVoice·2025년 1월 30일

리액트

목록 보기
8/14
post-thumbnail

React는 Vue나 Angular에 비해 자유로워 프레임워크가 아닌 라이브러리라고 불리지만, 템플릿이 아예 없진 않다. CRA나 vite를 통해 손쉽게 React 애플리케이션을 구축할 때 필요한 필수 파일들을 불러올 수 있다. 그러나 개발에 마법은 없는 법. 어떻게 이런 템플릿화가 가능했는지 알아보자.

1. React 앱의 기본 구성

HTML 파일 생성

리액트 애플리케이션이 실행될 기본 HTML 파일을 생성하고, React와 ReactDOM을 CDN으로 추가해준다. (이후를 위해 바벨도 추가한다.)

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>No CRA</title>
    <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
	<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    </head>
  <body>
    <div id="root"></div>
  </body>
</html>

2. Babel을 이용한 JSX 문법 적용

HTML 내에 리액트 문법을 사용한 script를 작성한다. 그러나 JS는 JSX를 이해하지 못한다! 그래서 syntax error가 발생하게 된다. 이를 해결하기 위해 Babel이 필요하다.

트랜스파일러

어떤 언어를 다른 기계가 이해하도록 다른 언어로 바꾸는 과정을 트랜스파일 또는 컴파일이라고 한다. 컴파일은 보통 고수준 언어를 기계어로 바꿔주는 과정을 말하기 때문에, Babel은 트랜스파일러라고 불린다. 우리는 Babel을 통해 JSX같은 최신 문법을 JS로 변경할 수 있다.

CDN을 통해 babel standalone을 가져오고 precompile을 위해 .babelrc파일을 작성하고 package.json에 해당 빌드 스크립트를 입력해준다. precompile을 하지 않으면 그 부담을 브라우저가 지기 때문에 경고가 발생한다.

// .babelrc : 바벨 설정 파일
{
  "presets": ["@babel/preset-react"]
}

// package.json
"scripts": {
    "build": "babel src -d dist"
 }

npm run build명령을 실행하면 dist폴더에 JS 문법으로 변환된 JS 파일이 생성된다.

3. 번들러 사용하기

번들러(Bundler)는 여러 개의 파일로 구성된 코드나 리소스를 하나의 파일(또는 몇 개의 파일)로 묶어주는 도구다. 여러 JS, CSS, 이미지 파일 등을 하나의 파일로 결합하여 배포 및 로드 성능을 개선하는 데 사용된다. 번들러가 없을 경우 브라우저는 한 번에 6개씩 나눠서 네트워크 요청을 가져오기 때문에 여러개의 파일이 있다면 그만큼 로드가 지연된다.

유명한 번들러로는 Webpack이 있다.

// webpack.config.js
const path = require("path");

module.exports = {
  entry: "./src/app.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  module: {
    rules: [
      //.css .js 등 서로 다른 확장자를 가진 파일을 처리할 때 어떤 규칙을 적용할지 정의
      {
        test: /\.js$/, // 어떤 파일을 대상으로 할지 정규표현식으로 작성
        exclude: /node_modules/, // node_modules 폴더는 제외
        use: {
          loader: "babel-loader", // babel-loader를 사용
        },
      },
    ],
  },
  mode: "development", // 없으면 warning
};

// package.json
"scripts": {
    "build": "webpack"
},

npm run build명령을 실행하면 dist폴더에 번들링된 파일인 bundle.js가 생성된다.

mode: development vs. production
production은 여러 최적화 및 유용한 기능을 제공한다 :
트리셰이킹 -> 불필요한 코드들을 없애는 것
코드 스플리팅 -> 한 파일에 있는 일부분의 코드만 필요할 경우 코드를 찢어주는 기능
코드 난독화 -> 중요 정보의 경우 가독성을 일부러 줄여 난독화 시키는 기능
그래서 production은 빌드가 오래 걸리지만, 사용자는 더 안전하고 빠른 만족스러운 경험을 할 수 있다.

4. 플러그인 사용하기

webpack(번들러)은 플러그인 기반으로 동작한다. 웹팩 규격에 맞는 플러그인을 설치하면 웹팩은 그 기능을 확장하여 그대로 사용 가능하다. 플러그인은 마치 USB 같다. 규격만 맞으면 USB 내에 들을 정보들을 활용할 수 있듯이 플러그인 기능들도 사용할 수 있는 것이다.

웹팩 플러그인은 빌드 과정 중 특정 기능을 추가하거나 개선하는 역할을 한다.
플러그인은 동기적으로 동작하기 때문에 위에서 아래로 순서를 지켜 작성해야한다.

HTML Webpack Plugin

파일 이름들에 해시값을 추가하여 캐시 문제를 해결하고자 하는 경우를 생각해보자. 이 설정을 하면 코드가 변경될 때마다 해시값이 추가된 새로운 파일 이름이 생성되어 파일이 변경되었는지 그대로인지 알 수 있게된다. 그러나 HTML 파일이 참조할 JS 파일명을 일일히 바꿔줄 수는 없는 노릇. 이를 해결해주는 플러그인이 존재한다.

// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");

...
output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.[contenthash].js'	// 해시값 추가
}
...
plugins: [
    new HtmlWebpackPlugin({	// HTML파일에 해시값 매칭시키기
	    template: "index.html",
        filename: 'index.html',
    })
]

명령어를 실행하면 dist파일에 해시값이 들어간 HTML파일이 생기게 된다.

Clean Webpack Plugin

JS파일이 변경될 때마다 새로운 해시값이 들어간 JS파일과 HTML파일이 생성되는데, 이전의 파일들은 쓸모가 없게 된다. 이런 파일들을 자동으로 정리해주는 플러그인이다.

const { CleanWebpackPlugin } = require("clean-webpack-plugin");

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

개발 서버 설정

빌드 환경이 아니라 개발 환경에서 개발을 하고 싶을 것이므로 개발 서버를 설정해 코드 변경 사항이 실시간으로 반영되도록 할 수 있다. webpack-dev-server를 설치하면 된다.

// webpack.config.js
devServer: {  // 빌드 환경이 아니라 개발 환경에서 개발을 하고 싶어! -> 개발 서버 설정
  static: { // 어떤 폴더를 참조할 것인가?
    directory: path.join(__dirname, "dist"),
  },
  port: 9000,
  open: true, // 서버 실행시 자동으로 브라우저를 연다
  hot: true,  // hot module replacement = hot reload 업데이트 실시간 변경
},
  
// package.json
"scripts": {
  "build": "webpack",
  "dev": "webpack serve"
},

환경 변수 관리

환경 변수는 빌드나 개발을 할 때 어떤 환경에서 하느냐에 따라 해당하는 값으로 변하는 변수를 말한다. Api key, 백엔드 url 등 상황에 따라 변해야하는 값이다.
dotenv-webpack을 사용해 환결 변수를 관리할 수 있다. .env파일을 통해 환경별 환경변수를 지정할 수 있다.

# .env.development
APP_API_URL=https://dev-api.example.com

# .env.production
APP_API_URL=https://api.example.com
// webpack.config.js
const DotenvWebpack = require("dotenv-webpack");

...
plugins: [
  new CleanWebpackPlugin(),
  new HtmlWebpackPlugin({
    template: "index.html",
    filename: "index.html",
  }),
  new DotenvWebpack({
    path: `./.env.${process.env.NODE_ENV || "development"}`,
  }),
],
  
// package.json
"scripts": {
  "build": "webpack",
  "start": "NODE_ENV=production webpack serve"	// 어떤 환경인지 명시
},
  
// App.js
const apiUrl = process.env.APP_API_URL; // 개발 파일에서 환경 변수 사용

크로스 개발환경 추가

윈도우 환경에서는 설정이 미묘하게 다르다. 각 환경에서 오류가 나지 않도록 변경해주기 위해서 cross-env를 설치해야한다.

"start": "cross-env NODE_ENV=development webpack serve"
profile
게임 QA 이직 준비중

0개의 댓글