Vite로 생성한 React 프로젝트 Github Pages로 배포하기

Contents

  • Vite란 무엇인가?
  • Vite로 React 프로젝트 빌드하기
  • Github Action 사용해서 Github Pages로 배포하기
  • Github Pages로 SPA처럼 동작하게 만들기
  • 마무리

1. Vite란 무엇인가? (vs CRA)

Vite와 Create-React-App(CRA)은 모두 React 프로젝트를 시작하는 데 사용되는 도구지만, 몇 가지 중요한 차이점이 있다.

Esbuild

Vite

  • 더 빠른 개발 서버 시작 및 핫 모듈 교체(HMR)
  • ESBuild을 이용한 번들링으로 빠른 빌드 시간
  • 다양한 프레임워크 지원 (React, Vue, Svelte 등)
  • 설정이 간단하고 커스터마이징이 쉬움
  • 최신 브라우저 기능을 활용하여 최적화된 빌드 결과물 생성

Create React App (CRA)

  • React 보일러 플레이트
  • 웹팩(Webpack) 기반의 번들링
  • React에 특화된 설정
  • 더 성숙하고 안정적인 생태계
  • 추가 설정 없이 바로 사용 가능한 다양한 기능 제공

주요 차이점

  • 성능: Vite가 일반적으로 더 빠른 개발 환경과 빌드 시간을 제공
  • 설정: Vite는 더 간단한 설정을 제공하며, CRA는 더 많은 기능이 미리 설정되어 있음
  • 유연성: Vite는 다양한 프레임워크를 지원하고 더 쉽게 커스터마이징 가능
  • 생태계: CRA는 더 오랜 기간 사용되어 왔기 때문에 더 넓은 생태계와 커뮤니티 지원을 가지고 있음

2. Vite로 React 프로젝트 빌드하기

이미 로컬에서 작동하는 React 프로젝트가 있다고 가정하고, Vite를 이용해 빌드해보자.

환경설정 (정적 파일 경로 설정)

루트에 있는 vite.config.ts(또는 vite.config.js)의 base를 설정해줘야 한다.

import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [react()],
  base: '/', // 여기에 repo 이름을 적는다
});

base에 repo 이름을 적을 때, 두 가지 경우로 나뉜다.

  • repo의 이름이 '<UserID>.github.io'라면 '/'로
  • 그렇지 않다면 '/<저장소 이름>/'으로

Github Pages는 정적 웹페이지로 배포하기 때문에 base의 설정이 필수적이다.

base는 root의 위치로 지정된다.

만약 public/favicon.ico가 있다면, Vite에서 코드를 작성할 때 src는 '/favicon.ico'로 설정해주면 된다.

이제 build할 준비가 되었다.

npm run build

터미널에서 이 명령어를 실행하면 dist 폴더에 빌드 결과물이 생성된다.

로컬에서 빌드 결과 테스트

npm run preview

dist 폴더에 생성된 빌드 파일은 로컬에서 테스트가 가능하다.
preview 명령어는 로컬 서버를 이용하여, 빌드된 프로젝트를 미리 보여준다.

주의사항

로컬의 빌드 파일을 직접 브랜치에 푸시해서 배포해도 상관없지만, 후술할 자동 빌드 및 배포 기능을 이용한다면 이 과정은 불필요하다.

따라서 .gitignore에 dist를 등록해야 한다.

3. Github Action 사용해서 Github Pages로 배포하기

build로 생성한 빌드 결과물을 Github Pages로 이제 배포해보자.

Github Actions Workflows 파일 생성

빌드할 Github의 repo의 Settings -> pages로 가서 SourceGithub Actions로 변경해준다.

Github Actions

그러면 자동으로 static.yml 파일이 생성되는데,

name: Deploy static content to Pages

on:
  push:
    branches: ['main']
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: 'pages'
  cancel-in-progress: false

jobs:
  build-and-deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Setup Pages
        uses: actions/configure-pages@v5

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v3
        with:
          path: './dist'

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v4

변경 후 repo로 푸시해주면 자동으로 빌드와 배포를 진행해준다.

4. Github Pages로 SPA처럼 동작하게 만들기

Github Pages는 정적이기 때문에 기본적으로 Single Page Application(SPA)을 지원하지 않는다.

하지만 약간의 트릭을 사용하면 SPA처럼 동작하게 만들 수 있다.

4.1 404.html 생성

public에 404.html로 해당 코드를 생성한다.

오픈 소스이기 때문에 MIT 라이센스를 반드시 명시해줘야한다.

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8">
    <script type="text/javascript">
      let segmentCount = 0;

      let l = window.location;
      let path = l.pathname.split('/').slice(0, 1 + segmentCount).join('/') + '/?p=/' +
                l.pathname.slice(1).split('/').slice(segmentCount).join('/').replace(/&/g, '~and~') +
                (l.search ? '&q=' + l.search.slice(1).replace(/&/g, '~and~') : '') +
                l.hash;

      // 현재 경로가 이미 올바른 경우, 리다이렉트하지 않음
      if (l.pathname.indexOf('/?p=/') === -1) {
        l.replace(
          l.protocol + '//' + l.hostname + (l.port ? ':' + l.port : '') + path
        );
      }
    </script>
    <title>motto</title>
  </head>
  <body>
  </body>
</html>

Github Pages는 정적 웹페이지이기 때문에, Router를 사용하게되면 404 Page를 렌더링한다.

이 때, 404 페이지로 다시 리다이렉트하게 로직을 구성하면 SPA처럼 동작하도록 구현할 수 있다.

4.2 index.html 수정

index.html의 head에 다음 script 코드를 넣어준다.

        <script type="text/javascript">

          (function (l) {
            if (l.search) {
              let q = {};
              l.search.slice(1).split('&').forEach(function (v) {
                let a = v.split('=');
                q[a[0]] = a.slice(1).join('=').replace(/~and~/g, '&');
              });
              if (q.p !== undefined && l.pathname !== q.p) {
                window.history.replaceState(null, null,
                  l.pathname.slice(0, -1) + (q.p || '') +
                  (q.q ? ('?' + q.q) : '') +
                  l.hash
            );
            }
        }
    }(window.location));
</script>

이 스크립트는 404에서 리다이렉트된 URL을 처리해준다.

마무리

이렇게 하면 Vite로 만든 React 프로젝트를 Github Pages에 배포하고, SPA처럼 동작하게 만들 수 있다.

또한 Github Actions의 워크플로우를 이용한 자동화로, 프로젝트를 업데이트할 때마다 main 브랜치에 변경사항을 푸시하기만 하면, Github Actions가 자동으로 빌드하고 배포할 수 있다.

Reference