프로젝트에서 앱을 만들어야 하는데 RN으로 개발하다가 이건 아니다 싶어서 찾아보다가 PWA를 선정하게 되었다.
PWA는 'Progressive Web Apps'의 줄인 말로, 모바일 사이트에서 네이티브 앱과 같은 사용자 경험을 제공하는 기술입니다. 웹과 앱 모두의 장점을 결합한 제품입니다.
흔히 웹앱이라고 하는 웹 페이지를 만드는 것인데 PWA는 핸드폰에서 사용하는 Native API를 사용할 수 있고 오프라인 상에서도 Service Worker라는 것을 이용해서 작업을 할 수 있다.
우리 프로젝트에 선정한 이유는 사실 카메라때문에 고민했었다.
QR 스캔이 주 기능인데 카메라를 사용하지 못하면 프로젝트가 망하기 때문에 찾아보다가
react-qr-reader
를 사용해봤는데 핸드폰으로 웹사이트에 들어가면 바로 카메라가 사용가능해서
RN에서 PWA로 갈아타게 되었다.
PWA기능은 나중에 정리하고 이번엔 PWA 기본 설정에 대해서 정리해보려한다.
우선 이번 프로젝트에서는 react + typescript + vite을 사용할 것이기 떄문에 vite 프로젝트를 생성해준다.
yarn create vite
이 명령어 입력하면
해서 프로젝트 생성해 준다.
그리고 기본 설정인
yarn
으로 패키지 설치해주고
yarn dev
해보면 잘 나온다.
이제 본격적으로 PWA 설정을 해야한다.
우선 아이콘을 준비해야 한다.
이 아이콘은 핸드폰 어플에서 보여줄 아이콘을 설정하는 것이다.
위 사진처럼 크기별로 아이콘을 준비하면 된다
📌 https://favicomatic.com/ 여기 사이트에서 512x512사이즈를 가져가서 다 변환하면 된다.
다음으로는 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"
}
]
}
이건 오프라인에서도 작업하기 위한 코드이다
루트폴더에 생성
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);
});
<!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은 Next.js 만든곳인데 배포가 너무 쉬워서 가끔 테스트 배포할때 자주 사용한다.
사용법 간단하게 설명하면
그래서 위에서 만든 프로젝트를 깃헙 레포지토리로 만들고 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",
},
},
},