React + TypeScipt + Vite PWA로 만들고 Vercel로 배포하기

jaehan·2023년 5월 6일
9

React

목록 보기
33/33
post-thumbnail

프로젝트에서 앱을 만들어야 하는데 RN으로 개발하다가 이건 아니다 싶어서 찾아보다가 PWA를 선정하게 되었다.

PWA란?

PWA는 'Progressive Web Apps'의 줄인 말로, 모바일 사이트에서 네이티브 앱과 같은 사용자 경험을 제공하는 기술입니다. 웹과 앱 모두의 장점을 결합한 제품입니다.

흔히 웹앱이라고 하는 웹 페이지를 만드는 것인데 PWA는 핸드폰에서 사용하는 Native API를 사용할 수 있고 오프라인 상에서도 Service Worker라는 것을 이용해서 작업을 할 수 있다.

선정 이유?

우리 프로젝트에 선정한 이유는 사실 카메라때문에 고민했었다.

QR 스캔이 주 기능인데 카메라를 사용하지 못하면 프로젝트가 망하기 때문에 찾아보다가

react-qr-reader를 사용해봤는데 핸드폰으로 웹사이트에 들어가면 바로 카메라가 사용가능해서

RN에서 PWA로 갈아타게 되었다.

설정방법

PWA기능은 나중에 정리하고 이번엔 PWA 기본 설정에 대해서 정리해보려한다.

1. 프로젝트 생성

우선 이번 프로젝트에서는 react + typescript + vite을 사용할 것이기 떄문에 vite 프로젝트를 생성해준다.

yarn create vite

이 명령어 입력하면

  • 프로젝트 이름 -> 기본 이름 vite-project로 생성
  • 어떤 프레임워크 사용할 건지 -> 여기선 React 라이브러리 선택
  • 언어 뭐선택할건지 -> swc가 빠르다는 얘기를 들어서 typescript + swc 선택

해서 프로젝트 생성해 준다.

그리고 기본 설정인

yarn 으로 패키지 설치해주고
yarn dev해보면 잘 나온다.

2. PWA 설정

이제 본격적으로 PWA 설정을 해야한다.

아이콘

우선 아이콘을 준비해야 한다.
이 아이콘은 핸드폰 어플에서 보여줄 아이콘을 설정하는 것이다.


위 사진처럼 크기별로 아이콘을 준비하면 된다
📌 https://favicomatic.com/ 여기 사이트에서 512x512사이즈를 가져가서 다 변환하면 된다.

manifest

다음으로는 manifest다

public/manifest.json

{
  "name": "vite-pwa",
  "short_name": "vite-pwa",
  "start_url": "/",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#485EEE",
  "icons": [
    {
      "src": "icons/icon-48x48.png",
      "sizes": "48x48",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "any maskable"
    },
    {
      "src": "icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}
  • short_name: 아이콘 아래에 표시될 이름
  • name: 설치 배너에 표시되는 이름
  • start_url: 스플래시 화면 다음에 시작 url -> 여기선 /
  • display: 웹앱 화면 설정
    browser: 기본 웹으로 실행
    standalone: url바 제거
    fullscreen: 전체 화면 사용

service worker

이건 오프라인에서도 작업하기 위한 코드이다

루트폴더에 생성
sw.js

// install event
self.addEventListener("install", (e) => {
  console.log("[Service Worker] installed");
});

// activate event
self.addEventListener("activate", (e) => {
  console.log("[Service Worker] actived", e);
});

// fetch event
self.addEventListener("fetch", (e) => {
  console.log("[Service Worker] fetched resource " + e.request.url);
});

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="theme-color" content="#8C383A" />
    <link rel="icon" href="icons/favicon.ico" />
    <link
      rel="alternate icon"
      href="icons/favicon.ico"
      type="ico"
      sizes="32x32"
    />
    <link
      rel="apple-touch-icon"
      href="icons/icon-152x152.png"
      sizes="152x152"
    />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="manifest" href="manifest.json" />
    <title>vite-project</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
    <script>
      if ("serviceWorker" in navigator) {
        // Register a service worker hosted at the root of the
        // site using the default scope.
        navigator.serviceWorker
          .register("/sw.js")
          .then((registration) => {
            console.log("Service worker registration succeeded:", registration);
          })
          .catch((err) => {
            console.log("Service worker registration failed:", error);
          });
      } else {
        console.log("Service workers are not supported.");
      }
    </script>
  </body>
</html>

이렇게 html파일에 서비스워커 불러와주고 head태그들을 추가해준다.

검사하기


개발자 도구에 들어가서 Lighthouse에 들어간 뒤에 위처럼 설정하고 파란색 버튼눌러서 pwa 설정이 다 되었는지 확인하면 된다.

그러면 이렇게 pwa에 체크가 나오는데 이게 pwa 설정 다 된거다!

vercel에 배포

vercel은 Next.js 만든곳인데 배포가 너무 쉬워서 가끔 테스트 배포할때 자주 사용한다.

사용법 간단하게 설명하면

  • 회원가입후 로그인
  • 내 깃헙 아이디 연동
  • 내 깃헙 레포지토리 하나 선택
  • 기본적인 npm install 이나 build 명령어를 사용하거나 내가 바꿀수 있다.
  • 빌드 누르면 에러 없으면 배포 완료됨

그래서 위에서 만든 프로젝트를 깃헙 레포지토리로 만들고 vercel에 들어가서 create new project 눌러서 들어가면 아래와 같이 나온다

그리고 아까 만든 프로젝트를 import 한다.


이 페이지에서 아래와 같은 부분이 있는데 그대로 하던가 알아서 override로 바꾸면 된다
Build Command: 빌드할때 사용할 커맨드 npm build, yarn build 같은거

Output Directory: build파일이 들어갈 폴더 기본적으로 dist

Install Command: 패키지 설치 커맨드 npm install, yarn install 같은거

위 프로젝트는 yarn이고 기본적이기 때문에 따로 바꾸지 않고 아래 deploy눌러준다.

그럼 알아서 빌드해주고 성공이 된다.

배포된 사이트에 들어가면 진짜 배포가 되고 오른쪽 위에 빨간 표시한걸 눌러보면 설치할 수 있다.

이렇게 설치할 수 있게 만들어 줬기 때문에 PWA로 이 어플을 사용할 수 있는 것이다.

핸드폰으로도 들어가서 홈화면에 추가하기 하면 manifest 파일에 추가한 아이콘이 바탕화면에 생겨서 어플처럼 사용할 수 있게 된다.

이렇게 PWA를 만들어 봤는데 앞으로 프로젝트 하면서 service worker같은 걸 더 깊게 공부해야할거 같지만 앞으로 많이 써먹을것 같다.

추가

이대로 배포하면 서비스 워커를 못불러 오는 오류가 있었다.

vite은 service워커를 모르기 때문에 아래와 같이 설정해줘서 sw.js파일을 따로 관리하도록 해줘야 한다!
_vite.config.ts

 build: {
    rollupOptions: {
      input: {
        main: "./index.html",
        sw: "./sw.js",
      },
    },
  },

0개의 댓글