mitmitwiki

PWA 적용 도전ㄱㅣ...!

kohi ☕ 2023. 4. 2. 01:08

PWA는 HTML, CSS, JS와 같은 웹 기술과 네이티브 앱의 장점을 결합한 것이다. 네이티브 앱을 개발하고 유지보수하는 것은 시간이나 비용이 상당히 소요되지만, PWA는 훨씬 더 빠르게 개발할 수 있고 푸시 알림이나 오프라인 지원과 같은 네이티브 앱의 특징들도 전부 제공할 수 있다.

 

PWA의 세 가지 구성 요소

  • HTTPS: PWA는 신뢰할 수 있는 연결 상태에서만 동작하기 때문에, 보안 연결을 통해서 서비스를 제공해야 한다.
    • 이번 프로젝트에서는 로컬 환경에서 시도했기 때문에 해당사항 X
  • servise worker: 서비스 워커는 백그라운드에서 실행되는 스크립트이다. 네트워크와 관련된 요청의 처리를 돕는다.
  • manifest: JSON 파일 형식이며 PWA가 표시되고 기능하는 방식에 대한 정보를 포함한다.

 

적용 과정

 

1. PWA용 Maskable 아이콘 제작

https://maskable.app/editor

 

Maskable.app Editor

Layers Export Share Maskable.app Editor lets you generate maskable PWA icons before adding them to your web app manifest. Maskable icons allow web developers to specify a full-bleed icon that will be cropped by the user-agent to match other icons on the de

maskable.app

 

2. manifest.json 추가

{
    "name": "HeyTossMe",
    "short_name": "HeyTossMe",
    "icons": [
        {
            "src": "/icons/maskable_icon_x48.png",
            "sizes": "48x48",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x72.png",
            "sizes": "72x72",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x96.png",
            "sizes": "96x96",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x128.png",
            "sizes": "128x128",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x192.png",
            "sizes": "192x192",
            "type": "image/png",
            "purpose": "any maskable"
        },
        {
            "src": "/icons/maskable_icon_x384.png",
            "sizes": "384x384",
            "type": "image/png"
        },
        {
            "src": "/icons/maskable_icon_x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ],
    "start_url": "/",
    "display": "standalone",
    "background_color": "#FFFFFF",
    "theme_color": "#ec7357"
}
  • name: 설치 페이지, 웹 스토어, 앱 관리 페이지 등에서 표시되는 이름
  • short_name: 앱을 설치했을 때 런처에서 보이는 이름
  • icons: ㅈㄱㄴ
  • start_url: 앱을 실행하면 표시되는 주소
  • display
    • browser: 일반적인 브라우저
    • standalone: 주소창이 사라진 형태
    • minimal-ui: standalone에서 뒤로 가기, 새로 고침 등의 키가 추가된 형태
    • fullscreen: 전체 화면으로 앱 표시
  • background_color: 앱이 로딩되는 동안 배경에 표시되는 색
  • theme_color: 툴바, 상단바 색상

 

3. root html에 manifest 추가

<link rel="manifest" href="/manifest.json" />

여기까지 문제 없으면 Application > manifest 이르케 됨 ▼

 

4. offline.html 추가

<!DOCTYPE html>
<html>
    <head>
        <title>Not Connected</title>
        <link
            href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/css/all.min.css"
            rel="stylesheet"
        />
        <meta name="viewport" content="width=device-width,initial-scale=1" />
        <style>
            body {
                width: 100%;
                min-height: 100vh;
                display: relative;
                margin: 0;
                padding: 0;
            }
            .wrapper {
                position: absolute;
                top: 50%;
                left: 50%;
                align-items: center;
                justify-content: center;
                -webkit-transform: translate(-50%, -50%);
                -moz-transform: translate(-50%, -50%);
                -ms-transform: translate(-50%, -50%);
                -o-transform: translate(-50%, -50%);
                transform: translate(-50%, -50%);
                text-align: center;
            }
            h1 {
                color: #ec7357;
                font-weight: bold;
                font-size: 50px;
                letter-spacing: 5px;
                line-height: 1rem;
                text-shadow: 0 0 3px #ec7357;
            }
            h4 {
                color: #ec7357;
                font-weight: 300;
                font-size: 16px;
            }
            .button {
                display: block;
                margin: 20px 0 0;
                padding: 15px 30px;
                letter-spacing: 5px;
                border-radius: 0.4rem;
                text-decoration: none;
                background-color: #ec7357;
                box-shadow: inset 0.2rem 0.2rem 1rem #ff7d5e, inset -0.2rem -0.2rem 1rem #bd5d46;
                color: white;
            }
        </style>
    </head>

    <body>
        <!-- This file lives in public/404.html -->
        <div class="wrapper">
            <h1>OFFLINE</h1>
            <h4>Please check your internet connection</h4>
            <a href="https://github.com/hey-tossme" class="button">github</a>
            <a
                href="https://www.notion.so/trustmitt/0224991ff0d945879625f77d6a99218b"
                class="button"
                >notion</a
            >
        </div>
    </body>
</html>

 

5. service-worker.js 추가

const CACHE_NAME = "cache-v1";

const FILES_TO_CACHE = ["/offline.html", "/public/icons/favicon.ico"];

self.addEventListener("install", (event) => {
    event.waitUntil(caches.open(CACHE_NAME).then((cache) => cache.addAll(FILES_TO_CACHE)));
});

self.addEventListener("activate", (event) => {
    event.waitUntil(
        caches.keys().then((keyList) =>
            Promise.all(
                keyList.map((key) => {
                    if (CACHE_NAME !== key) return caches.delete(key);
                })
            )
        )
    );
});

self.addEventListener("fetch", (event) => {
    if ("navigate" !== event.request.mode) return;

    event.respondWith(
        fetch(event.request).catch(() =>
            caches.open(CACHE_NAME).then((cache) => cache.match("/offline.html"))
        )
    );
});

 

6. 해당 코드 작성 후 root html 파일에 스크립트 태그 추가

        <script>
            if ("serviceWorker" in navigator) {
                window.addEventListener("load", () => {
                    navigator.serviceWorker.register("/service-worker.js");
                });
            }
        </script>

 

여기까지 완료하면 일어나는 일

성능 점수 눈치껏 못본 척해라

 

오프라인일 때 offline.html

 

이 놈 자식을 열어보면은

 

간지가 폭발하는 웹 애플리케이션이 낙타나고

바탕화면에 바로가기도 생김

 

레퍼런스

너무 많이 참고했어요 감사합니다

https://marshallku.com/web/tips/%EC%9B%B9-%EC%82%AC%EC%9D%B4%ED%8A%B8%EB%A5%BC-pwa%EB%A1%9C-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8%ED%95%98%EA%B8%B0

 

웹 사이트를 PWA로 업데이트하기

PWA(Progressive Web App)란 웹은 높은 접근성을 가진 매력적인 플랫폼입니다.한 번의 코딩으로 거의 모든 기기에서 접근할 수 있고, 검색이나 주소의 공유로 누구나 어디에서나 접속할 수 있습니다.

marshallku.com