React

PWA(Progressive Web App)

코딩 화이팅 2025. 1. 26. 15:19

웹사이트를 안드로이드 / iOS 모바일 앱처럼 사용할 수 있게 만드는 웹개발 기술

웹사이트를  PWA화 시키면 좋은 점

  • 스마트폰, 태블릿 바탕화면에 웹사이트를 설치 가능
    • 설치된 앱 누르면 상단 URL바가 제거된 크롬 브라우저가 뜬다.
  • 오프라인에서도 동작 가능
    • service-worker.js  라는 파일과 브라우저의 Cache storage 덕분에 가능
    • 자바스크립트로 게임 만들 때 유용
  • 설치 유도 비용이 매우 적다
    • 앱설치를 유도하는 마케팅 비용이 적게 들어 좋을 수 있다.
    • 구글플레이 스토어 방문해서 앱 설치하고 다운받게 하는 건 항상 매우 높은 마케팅 비용이 든다.
    • 하지만 PWA라면 웹사이트 방문자들에게 간단한 팝업을 띄워서 설치 유도할 수 있으니 훨씬 적은 마케팅 비용이 든다.

PWA 만드는 법

  • 사이트 파일 2개만 사이트 로컬경로에 있으면 브라우저가 PWA로 인식한다.(HTTPS 사이트여야된다.)
  • manifest.json과 service-worker.js 라는 이름의 파일 두개를 만들면 된다.
    • 하지만 기본 프로젝트를 npm build / yarn build 했을 경우 manifest.json 파일만 생성해준다.
npx create-react-app 프로젝트명 --template cra-template-pwa
  • 이렇게 터미널에 입력하여 service-worker.js까지 자동으로 생성을 원한다면 프로젝트를 처음 만들 때 이렇게 터미널에 입력해주면 된다.
  • 따라서 프로젝트 중간에 PWA로 바꿀 순 없다.
    1. 바꾸고 싶다면 다른 폴더에 위 명령어를 이용해 프로젝트 새로 하나 만든 다음에
    2. 기존 프로젝트의 App.js같은 다른 파일들을 새 프로젝트로 복붙
      index.js 같은 파일은 많이 바뀐점이 있을거라 차이점만 잘 복붙하면 된다.
    3. router, redux 같은 라이브러리를 설치했다면 그것도 새 프로젝트에서 다시 설치
serviceWorkerRegistration.unregister();
=>
serviceWorkerRegistration.register();
  • 파일들 중 index.js 하단에 윗부분을 아래처럼 수정해주면된다.
  • 그럼 이제 yarn build / npm run build 했을 때 manifest.json과 service-worker.js 파일이 자동으로 생성된다.

manifest.json

{
  "version" : "여러분앱의 버전.. 예를 들면 1.12 이런거",
  "short_name" : "설치후 앱런처나 바탕화면에 표시할 짧은 12자 이름",
  "name" : "기본이름",
  "icons" : { 여러가지 사이즈별 아이콘 이미지 경로 },
  "start_url" : "앱아이콘 눌렀을 시 보여줄 메인페이지 경로",
  "display" : "standalone 아니면 fullscreen",
  "background_color" : "앱 처음 실행시 잠깐 뜨는 splashscreen의 배경색",
  "theme_color" : "상단 탭색상 등 원하는 테마색상",
}
  • build 하고 나면 build 폴더 내에 이 파일들이 있다.
  • manifest.json 파일은 웹앱의 아이콘, 이름, 테마색 이런걸 결정하는 부분
  • version, scope 등 다른 항목들도 넣을 수 있다.
<link rel="manifest" href="/manifest.webmanifest">
  • 그리고 이 파일은 웹앱에서 사용하는 모든 html 안에 이런 식으로 넣어야하지만 리액트가 자동으로 해준다.

service-worker.js

  • 기본 카카오톡 같은 앱 설치할 때 구글플레이 스토어 가서 설치한다.
    • 그럼 카톡 구동에 필요한 이미지, 데이터들이 전부 하드에 설치된다.
    • 그리고 카톡을 켜면 카톡 로고 같은 데이터를 카톡 서버에 요청하는 게 아니라 하드에 이미 설치되어 있는 걸 그대로 가져와서 쓰게된다.
    • 이걸 흉내내도록 도와주는 파일이 바로 service-worker 라는 파일이다.
  • 이 파일에 설정을 잘 해주면 이제 웹앱을 설치했을 때 어떤 CSS, JS, HTML, 이미지 파일이 하드에 설치될지 결정할 수 있다.
    • 그럼 이제 다음에 앱을 켤 때마다 서버에 CSS, JS, HTML 파일을 요청하는게 아니라 Cache Storage에 저장되어 있던 CSS, JS, HTML 파일을 사용하게 된다. (그럼 이제 오프라인에서도 사용이 가능)
    • 근데 설정이 이미 되어있기 때문에 따로 설정해줄 필요는 없음.
  • 저장해두기 싫은 자주 변하는 파일들이 간혹 있다면 하단 튜토리얼을 참고해서 수정 가능
  • 쌩으로 service worker 파일을 만들고 싶다면 구글 공식 튜토리얼이나 크롬브라우저 권장 튜토리얼 참고
    https://developers.google.com/web/fundamentals/primers/service-workers
 

서비스 워커 개요  |  Workbox  |  Chrome for Developers

서비스 워커의 개요입니다.

developer.chrome.com

  • 홈페이지 업데이트할 때마다 유저들이 올드한 JS 파일을 사용하진 않을까 걱정 안해도 된다.
    • build할 때마다 JS, CSS, HTML 파일의 이름과 경로가 무작위로 바뀜.
    • 사이트에 필요한 JS, CSS, HTML 파일명이 바뀌면 하드에 있는게 아니라 서버에 요청해서 새로 받아오기 때문에 파일을 서버에 올려서 배포할 때 마다 유저는 새로운 파일을 보게 된다.

개발자 도구로 PWA 디버깅

  • build한 프로젝트가 PWA인지 아닌지 살펴보고 싶으면 사이트를 호스팅 받아 올리거나(Github pages 이런 것도 된다.)
  1. VScode 익스텐션 중에 live server 이걸 검색해서 설치하고
  2. build 폴더를 에디터로 오픈하고
  3. 거기 있는 index.html을 우클릭 - live server로 띄우기 누르면 된다.

  • 사이트에서 크롬 개발자도구를 켜면 Application 이라는 탭이 있다
    • 여기 들어가면 PWA와 관련된 모든걸 살펴볼 수 있다.
    • 사이트가 없다면 flipkart.com 이런 PWA 사이트 들어가서 따라해보면 된다.
      • Manifest 메뉴에선 manifest.json 내용들을 확인 가능
      • Service Worker 메뉴에선 service-worker 파일이 잘 있는지 오프라인에선 잘 동작하는지 테스트 가능하고 푸시알림 기능을 개발해놨다면 푸시알림도 샘플로 전송해볼 수 있다.
      • Cache Storage 메뉴에선 service-worker 덕분에 하드에 설치된 CSS, JS HTML 파일들을 확인할 수 있고 캐시된 파일 제거도 가능

PWA를 커스터마이징하려면?

  • 지금 PWA 발행이 쉽고 간단한 이뉴는 구글의 workbox 라는 라이브러리 덕분
    • 이게 create-react-app 설치할 때 함께 설치되었기 때문
    • 따라서 PWA 발행 방식 같은 걸 커스터마이징 하고 싶으면 workbox 사용법을 익혀야된다.
  • 빠르게 커스터마이징 방법 하나 배운다면?
    하드에 설치할 파일 중 HTML을 제외하고 싶다면?
    • HTML 파일은 너무 자주 변해서 하드에 저장해놓기 싫다면 여길 수정해야된다.
    • 하지만 이러면 앱 실행 시 아무것도 안 뜰거고 모바일 앱의 장점이 사라진다.
// 구버전
new WorkboxWebpackPlugin.GenerateSW({
    clientsClaim: true,
    exclude: [/\.map$/, /asset-manifest\.json$/],
})

// 신버전
new WorkboxWebpackPlugin.InjectManifest({
    swSrc,
    dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
    exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
  • 폴더 내의 node_modules/react-scripts/config/webpack.config.js 파일을 찾으면 위와 같은 코드가 있다.
  • exclude 라는 항목이 어떤 파일을 캐싱하지 않을건지 결정하는 부분
  • 정규식으로 작성하는데 정규식과 일치하는 파일명을 제외
  • 따라서 원하는 HTML 파일을 여기 등록하면 끝
new WorkboxWebpackPlugin.GenerateSW({
    clientsClaim: true,
    exclude: [/\.map$/, /asset-manifest\.json$/, /index\.html/],
})
  • 이렇게 코드를 추가하면 build할 때 index.html 파일을 캐싱목록에서 제외해주게 된다.
  • 이거 말고도 '모든 .css로 끝나는 파일', 'a라는 글자로 시작하는 파일' 이런 식으로 정규식으로 작성할수도 있다.
  • 하지만 사이트가 페이스북, 인스타처럼 입장과 동시에 Ajax로 초기데이터들을 전부 받아오는 사이트라면 굳이 HTML 파일을 이렇게 할 필요는 없다.
  • PWA는 구글 앱스토어에 올릴 수 있는 apk 파일로 변환 가능
    PWAbuilder 등을 이용하면 된다.