본문 바로가기
공부/프로그래밍

[react, nextjs] PWA(프로그레시브 웹 앱) 적용하기

by demonic_ 2022. 6. 24.
반응형

현재 다니는 회사에서 앱을 만들 수는 없을거 같아 웹 기반으로 하고 있는데 PWA를 알게되어 적용해보기로 했다.2가지를 기대하고 있는데 다음 목적이 있기 때문이다

 

  1. 모바일 홈에서 앱처럼 보이게 하여 바로 접속할 수 있도록 하기
  2. (나중에 있을) 푸시기능 활용

 

해서 적용방법을 정리한다.

 

 

 

1. npm 에서 다운로드

아래 링크를 들어가면 next에 pwa를 적용하는 방법이 있다.

https://www.npmjs.com/package/next-pwa

 

next-pwa

Next.js with PWA, powered by workbox.. Latest version: 5.5.4, last published: 16 days ago. Start using next-pwa in your project by running `npm i next-pwa`. There are 41 other projects in the npm registry using next-pwa.

www.npmjs.com

 

 

처음에 이걸 몰랐을 때는 react-pwa를 생각했었는데 다행이 next에서도 적용하는 방법이 있어서 이걸 적용하기로 했다.

 

설치

 

npm install next-pwa

 

 

적용을 위해선 next.config.js 파일에 다음의 설정내용을 추가해야 한다.

반드시 pwa: {dest :'public'} 이 설정되어야 한다. 그렇지 않으면 다른 곳에 설치되어 서비스워커를 설정하지 못한다

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public'
  }
})

 

 

적용을 위해선 next.config.js 파일에 다음의 설정내용을 추가해야 한다.

반드시 pwa: {dest :'public'} 이 설정되어야 한다. 그렇지 않으면 다른 곳에 설치되어 서비스워커를 설정하지 못한다

const withPWA = require('next-pwa')

module.exports = withPWA({
  pwa: {
    dest: 'public'
  }
})

 

이상태로 즉각 반영이 되는건 아니고, next build를 하게되면 public 위치에 관련파일 (workbox-*.js, sw.js) 파일이 생성된다. 그래서 build를 해보면 다음처럼 콘솔에 찍히는걸 꼭 확인해봐야 한다

info  - Checking validity of types  
warn  - The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config
> [PWA] Compile client (static)
> [PWA] Auto register service worker with: /Users/dgpark/git/side-project/procyan/web-frontend/node_modules/next-pwa/register.js
> [PWA] Service worker: /Users/dgpark/git/side-project/procyan/web-frontend/public/sw.js
> [PWA]   url: /sw.js
> [PWA]   scope: /
> [PWA] Compile server
> [PWA] Compile server

 

만약 설정이 잘못되었다면 [PWA] ... 라고 나오는 로그가 안나오니 꼭 확인하자.

 

 

 

2. 아이콘 생성 및 등록

512 크기의 아이콘을 준비해서 아래 사이트에서 크기별로 생성한다.

https://favicomatic.com/done

 

The ultimate favicon generator - Favic-o-Matic

Check this amazing tool, it creates EVERY kind of favicon you need, including iOS icons, Android icons, Metro tile icon and more! Favic-O-Matic is the FIRST favicon generator to correctly handle transparent favicon from png!

favicomatic.com

 

생성하고 나면 크기별로 파일을 다운로드 받을 수 있고 head 태그 내에 넣을 값들을 만들어 준다.

 

 

받은 파일은 적절한 위치에 넣어주도록 하자. 내 경우는 public/icons 라는 곳에 넣었다.

그리고 위에서 복사한 경로를 _document.tsx 파일 내에 넣어두었다.

주의해야 할 것이 해당 사이트는 apple-touch-icon-precomposed 라고 표기되는데 apple-touch-icon로 변경되어야 한다. 설정방법은 아래 참고.

import Document, {Head, Html, Main, NextScript} from "next/document";

...
    render() {
        return (
            <Html lang={"en"}>
                <Head>
                    <meta charSet={"utf-8"}/>
                    <link rel="manifest" href="/manifest.json" />
                    <meta name='theme-color' content='#000000' />
                    <link rel="apple-touch-icon" sizes="57x57" href="./icons/apple-touch-icon-57x57.png" />
                    <link rel="apple-touch-icon" sizes="114x114" href="./icons/apple-touch-icon-114x114.png" />
                    <link rel="apple-touch-icon" sizes="72x72" href="./icons/apple-touch-icon-72x72.png" />
                    <link rel="apple-touch-icon" sizes="144x144" href="./icons/apple-touch-icon-144x144.png" />
                    <link rel="apple-touch-icon" sizes="60x60" href="./icons/apple-touch-icon-60x60.png" />
                    <link rel="apple-touch-icon" sizes="120x120" href="./icons/apple-touch-icon-120x120.png" />
                    <link rel="apple-touch-icon" sizes="76x76" href="./icons/apple-touch-icon-76x76.png" />
                    <link rel="apple-touch-icon" sizes="152x152" href="./icons/apple-touch-icon-152x152.png" />
                    <link rel="icon" type="image/png" href="./icons/favicon-196x196.png" sizes="196x196" />
                    <link rel="icon" type="image/png" href="./icons/favicon-96x96.png" sizes="96x96" />
                    <link rel="icon" type="image/png" href="./icons/favicon-32x32.png" sizes="32x32" />
                    <link rel="icon" type="image/png" href="./icons/favicon-16x16.png" sizes="16x16" />
                    <link rel="icon" type="image/png" href="./icons/favicon-128.png" sizes="128x128" />
                    <meta name="msapplication-TileColor" content="#FFFFFF" />
                    <meta name="msapplication-TileImage" content="mstile-144x144.png" />
                    <meta name="msapplication-square70x70logo" content="mstile-70x70.png" />
                    <meta name="msapplication-square150x150logo" content="mstile-150x150.png" />
                    <meta name="msapplication-wide310x150logo" content="mstile-310x150.png" />
                    <meta name="msapplication-square310x310logo" content="mstile-310x310.png" />
...

 

 

 

3. manifest.json 등록

이제 manifest.json을 작성할 차례다.

manifest.json 파일이름을 만들어서 public 테이블에 넣는다.

파일 내 정보는 다음처럼 구성한다

 

아이콘이 부족하면 PWA 통과가 잘 안되는 경우가 많다. 꼭 제대로 등록해주도록 하자

내 경우 512x512 사이즈를 준비해서 같이 넣어주었는데, 이 아이콘이 없어서 error메세지가 나왔다. 처음부터 512x512 사이즈로 작업 시작하는 것을 추천한다.

(public/icons/ 폴더 내에 넣어두었다)

{
  "short_name": "APP 이름",
  "name": "APP 이름",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "icons": [
    {
      "src": "./icons/apple-touch-icon-57x57.png",
      "sizes": "57x57",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-60x60.png",
      "sizes": "60x60",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-76x76.png",
      "sizes": "76x76",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-114x114.png",
      "sizes": "114x114",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-120x120.png",
      "sizes": "120x120",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "./icons/apple-touch-icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "./icons/favicon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    },
    {
      "src": "./icons/favicon.ico",
      "sizes": "64x64",
      "type": "image/icon",
      "purpose": "any maskable"
    }
  ]
}

 

display 에 standalone 를 설정해 두어야 앱으로 생성되었을때 주소와 버튼칸이 숨겨진다.

theme_color 은 PWA의 상태바 색이고, background_color 는 splash 화면에서 배경색을 의미한다.

 

이렇게 설정해 두었다면 이제 빌딩해보자

npm run build && npm run start

 

 

실행한 뒤에 크롬 브라우저에서 접속하여 개발자 도구(F12) => Lighthouse 탭을 클릭한다.

프로그레시브 웹 앱만 선택한 뒤에 왼쪽 보고서 생성을 클릭한다.

 

아래와 같이 성공이 뜨면 PWA가 잘 적용되었다는 뜻이다.

 

마지막 줄인 '매니페스트에 마스크 가능한 아이콘이 없음'이 보이는데, manifest.json 파일 내 icons 라는 배열에 적힌 것 중 하나에 다음의 옵션을 추가하면 된다.

"purpose": "any maskable"

...
"icons": [
    {
      "src": "./icons/favicon.ico",
      "sizes": "64x64",
      "type": "image/icon",
      "purpose": "any maskable"
    }
...

설정후에 다시 실행하면 모두 클리어 된 것을 확인할 수 있다.

 

만약 이번 포스팅에 적힌것과 관계없는 에러가 있을 경우 각각의 상황에 맞춰 해결해주면 된다.

다만 '페이지와 start_url을 제어하는 서비스 워커를 등록' 관련 에러가 있다면 PWA를 제대로 실행하고 있는지(npm run build 할 때 콘솔에 [PWA]... 이 잘 뜨는지) 꼭 확인하여야 한다. 서비스워커가 설정되어 있지 않다면 아래와 같이 에러가 발생한다

 

설치가 완료되면 브라우저 상단에 다운로드 버튼이 생긴다. 클릭하면 다음과 같은 팝업이 뜬다.

모바일에서 보면 화면 하단에 팝업으로 보이거나 더보기 매뉴에

 

 

 

팁)

next.config.js 파일에 멀티 플러그인을 사용하고 있다면 next-compose-plugins 를 이용해 다음처럼 설정한다.

const withPlugins = require("next-compose-plugins");
const withImages = require('next-images')
const withPWA = require("next-pwa")


let withPWACustom = withPWA(
    {
        pwa: {dest: "public"}
    }
);

module.exports = withPlugins([withPWACustom, withImagesCustom])

 

플러그인 설정이 잘못되어도 서비스워커를 설정하지 못하니 꼭 console 창에 [PWA]... 이 같이 뜨는지 확인해보자.

 

 

 

끝.

 

참고:

https://www.npmjs.com/package/next-pwa

 

next-pwa

Next.js with PWA, powered by workbox.. Latest version: 5.5.4, last published: 16 days ago. Start using next-pwa in your project by running `npm i next-pwa`. There are 41 other projects in the npm registry using next-pwa.

www.npmjs.com

https://web.dev/i18n/ko/maskable-icon-audit/

 

매니페스트에 마스크 가능 아이콘 없음

PWA에 마스크 가능 아이콘 지원을 추가하는 방법을 알아보세요.

web.dev

https://kwanghyuk.tistory.com/200

 

[React.js] react app을 PWA로 만들기

PWA - Progressive Web App 브라우저에서 실행되는 Web App을 마치 네이티브 앱처럼 만들어 주는 기술이다. 네이티브 앱"처럼" 이기때문에 네이티브의 기능을 사용할 순 없지만 읽기 속도, 표시 속도, 오

kwanghyuk.tistory.com

 

반응형

댓글