티스토리 뷰

WEB

[PWA] 자바스크립트로 PWA 개발

마시멜로co. 2020. 10. 26. 16:07

자바스크립트로만 PWA를 개발해보겠습니다.

 

단계별로 하나하나씩 PWA를 완성해보도록 하겠습니다.

 

 

 

1. 프로젝트 생성

우선 VSCode를 열어 폴더(프로젝트)를 만듭니다. (파일 -> 폴더열기 -> 폴더생성 후 폴더 클릭 -> 폴더 선택)

저는 PWA_TEST 폴더를 만들었습니다.

프로젝트(폴더) 마우스를 올리면 새파일 아이콘이 나타납니다. 새파일 아이콘 클릭 후 index.html 파일을 만듭니다.

index.html 파일을 열어 html5 파일로 만들어줍니다. 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

index.html 파일은 PWA의 메인화면이 됩니다.

 

 

2. 매니페스트 작성하기

manifest.json 파일 이름으로 새파일을 만들어주세요

manifest.json 을 작성해봅시다. 

manifest.json
0.00MB

{
    "name": "PWA 테스트 앱",
    "short_name": "바로가기 이름",
    "description": "PWA를 공부하기 위한 프로젝트입니다.",
    "scope": ".",
    "start_url": "./",
    "display": "fullscreen",
    "orientation": "portrait",
    "theme_color": "#ffffff",
    "background_color": "#ffffff",
    "icons": [
      {
        "src": "images/icons/android-chrome-512x512.png",
        "sizes": "512x512",
        "type": "image/png"
      }
    ]
  }

매니페스트는 PWA의 신분증과도 같습니다.

PWA에 대한 모든 정보가 표시됩니다. 

 

name : 바로가기 아이콘설치를 권장하는 팝업배너, 스플래시 스크린에 표시되는 제목

short_name : 바탕화면 바로가기 아이콘 아래 표시되는 제목

description : 애플리케이션의 간단한 설명 혹은 자기소개 문장

                 (PWA를 수집하는 웹 크롤러가 있다면 description에 있는 정보를 가져옵니다.)

scope : 매니페스트에 정의된 내용이 적용될 수 있는 파일들의 범위를 지정 

                 '.' 현재위치 './' 현재위치를 중심으로 시작하는 하위 폴더를 의미

start_url :  프로그램을 실행하면 시작될 URL을 루트경로(./)로 설정

                 (루트경로는 시작하는 경로를 의미 반드시 .으로시작해야됩니다.)

display : PWA를 실행하면 나타나는 화면의 형태를 설정.

옵션 의미
fullscreen 기기의 최대화면으로 보여준다. 만약 기기의 운영체제가 풀스크린을 지원하지 않으면, standalone으로 자동 설정된다.
standalone 웹 브라우저의 주소, 상태 표시줄 등을 모두 제거한 화면을 보여준다. 즉, 웹 브라우저처럼 보이지 않도록 실행할 수 있다. 일반적으로 가장 많이 사용한다.
minimal-ui 상단에 주소 표시줄만 추가한다. 만약 기기의 운영체제가 minimal-ui를 지원하지 않으면 standalone으로 자동 설정된다.
browser 웹 브라우저와 똑같은 모습으로 실행된다. (다른 옵션과 달리 앱이아닌 웹으로 인식)

orientation : 화면의 방향을 결정하는 속성입니다.

                 portrait 세로로 실행 / landscape 가로로 실행

theme_color : 상태표시줄의 색상 설정

background_color : 스플래시 화면의 배경색 설정

icon : 바로가기 앱이 설치될때 사용되는 아이콘 이미지

 

참고로 스플래시 스크린에 사용할 아이콘 이미지 중에서 128dpi 에 가장 가까운 이미지를 찾아 화면에 표시합니다.

여기서 512x512px 크기의 아이콘 하나만 사용했습니다. 

 

매니페스트가 알맞게 작성되었는지 검사하기 위한 웹사이트(manifest-validator.appspot.com/) 에 접속하여 유효성 검사를해보시면 좋습니다. 

 

3. 메인 화면 작성하기

위에 작성한 매니페스트를 index.html에 연결작업이 필요합니다.

index.html
0.00MB

<!DOCTYPE html>
<!-- 언어를 한글로 설정 -->
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <!-- PWA 매너페스트 파일 연결, 상태바 테마색상을 흰색으로 변경 -->
    <link rel="manifest" href="manifest.json">
    <meta name="theme-color" content="#ffffff">
    <!-- 모바일 기기 뷰포트, 브라우저 주소 표시줄의 파비콘 설정  -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="shortcut icon" href="images/icons/favicon.ico">
    <link rel="icon" type="image/png" sizes="16x16" href="images/icons/favicon-16x16.png">
    <link rel="icon" type="image/png" sizes="32x32" href="images/icons/favicon-32x32.png">
</head>

언어설정은 필수 입니다. 언어를 설정하지 않으면 PWA를 실행할때마다 , 다른 언어로 번역하시겠습니까? 라는 질문을 받습니다.

 

매니페스트 파일을 연결하기 위해 <link>태그를 이용하여 PWA 프로젝트와 연결하였습니다.

viewport 설정은 모바일 브라우저로 PC용 사이트에 저복하면 가끔 화면이 작게 보이는 경우가 있습니다. 포트를 설정하지 않았기 때문입니다. 이 문제를 해결하려면 content의 속성값을 설정해야합니다.

옵션 의미
width=device-width 모바일 기기의 해상도로 너빗값 자동설정
initial-scale=1.0 모바일 기기에서 확대/축소 기능 허용
user-scalable=no 모바일 기기에서 확대/축소 기능 제한

파비콘은 브라우저의 탭이나 즐겨찾기옆에 있는 아이콘을 말합니다. 

 

메인 화면을 디자인 하기 위해 css 코드와 <body> 안에 넣을 태그를 작성하여야 합니다.

가장 기본적인 페이지 구성을 해보도록 하겠습니다.

<style>
    html,
    body {
      /* html, body 모두 높이를 100%로 고정시켜야 flexbox 동작 */
      height: 100%;
      background-color: #F3A530;
      color: #ffffff;
    }

    .container {
      height: 100%;
      /* 높이를 100%로 고정시킴 */
      display: flex;
      /* 컨테이너를 flexbox 스타일로 변경 */
      align-items: center;
      /* 상하 가운데 정렬 */
      justify-content: center;
      /* 좌우 가운데 정렬*/
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>HELLO PWA</h1>
    <img src="./images/icon-main.png" alt=""></img>
    <p>by javascript</p>
  </div>
  </body>

화면에 표시할 글자와 이미지는 플렉스 박스(flex box)로 레이아웃을 배치합니다. 플렉스 박스를 사용하면 모바일의 기기의 크기를 자동으로 고려해 최적의 레이아웃을 배치할 수 있습니다.

이 플렉스 박스를 사용하려면 반드시 html,body의 높이를 100%로 고정해야합니다.

 

4. 서비스 워커 만들기

서비스 워커는 브라우저와 분리되어 독립적으로 실행할 수 있습니다. 서비스 워커는 캐시, 푸시알림, 웹 API와 연동 등 다양한 기능을 별도로 수행할 수 있습니다.

 

서비스워커 입문을 위하여 우선 필요한 파일을 캐시하여 메모리에 저장하는 서비스워커를 만들어보겠습니다.

프로젝트에 service_worker.js 파일을 생성합니다.

service_worker.js
0.00MB

const sCacheName ="practice-pwa";//캐시 이름 선언
const aFilesToCache = ['./','./index.html','./manifest.json','./icon-main.png'];//캐시할 파일 선언

//서비스워커 설치하고 캐시파일 저장
self.addEventListener('install', pEvent => {
    console.log('서비스워커를 설치합니다.');
    pEvent.waitUntil(
        caches.open(sCacheName)
        .then(pCache => {
          console.log('파일을 캐시에 저장합니다.');
          return pCache.addAll(aFilesToCache);
        })
      );
});
// 고유번호 할당받은 서비스 워커 동작 시작
self.addEventListener('activate', pEvent => {
    console.log('서비스워커 동작 시작');
});


//데이터 요청시 네트워크 또는 캐시에서 찾아 반환 
self.addEventListener('fetch', pEvent => {
    pEvent.respondWith(
      caches.match(pEvent.request)
      .then(response => {
        if (!response) {
          console.log("네트워크에서 데이터 요청!", pEvent.request)
          return fetch(pEvent.request);
        }
        console.log("캐시에서 데이터 요청!", pEvent.request)
        return response;
      }).catch(err => console.log(err))
    );
  });

 

index.html에 작성한 서비스워커를 연결해봅니다.

<body>
  ...생략
  <!-- 1. 서비스 워커 등록 -->
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker
        .register('./service_worker.js')
        .then(function () {
          console.log('서비스 워커가 등록됨!');
        })
    }
  </script>
</body>

이제 서버를 시작해서 구글 개발자 도구(F12)로 적용이 잘되어있는지 확인해봅니다.

크롬 개발자도구(F12)를 열어 Application 탭 클릭 -> Cache Storage 클릭 서비스워커가 정상동작하는 지를 확인합니다.

서비스 워커의 생애 주기는 install -> activate -> fetch 순서로 이벤트를 발생시킵니다. 

 

 install 이벤트(서비스 워커 설치 및 캐시파일 저장)은 말그대로 PWA를 설치하는 단계입니다.  install 이벤트의 상태는 설치 진행과 설치 진행 완료 후 대기로 구분합니다.

서비스 워커가 제대로 설치되면 pEvent에 포함된 waitUntil() 함수를 이용해 캐시에 필요한 파일을 저장합니다.

서비스 워커가 준비될 때 캐시를 저장하는 것을 프리캐시 (pre-cache)라고 하며 waitUntil() 함수는 installing 상태에서 프리 캐시가 완료될 때까지 대기합니다. 

 

서비스워커가 고유한 ID를 발급받아 브라우저에 성공적으로 등록하면 activate 이벤트(서비스 워커 업데이트)가 동작합니다. 앱을 업데이트하면 서비스 워커도 새로운 내용으로 교체해야합니다. 이럴떄 호출되는 이벤트가 activite 이벤트입니다. 

activite 이벤트의 상태는 활성 중과 활성 후 로 나눌 수 있습니다. 서비스 워커의 내용을 업데이트 하려면 먼저 캐시 파일을 변경해 새로운 서비스 워커 ID로 새로운 캐시 내용이 설치되도록 해야합니다. 

 

그리고 activiting 상태에서 waitUntil()함수를 사용해서 기존 캐시를 제거하는 코드를 넣습니다. 

 

만약 테스트 시에 이작업이 번거롭다면 

크롬 개발자 도구에서 Application 탭클릭 -> Service workers 에서 Update on reload를 체크하여 줍니다.

그러면 기존의 서비스 워커 ID를 제거하고 새로운 아이디를 부여해 install 이벤트 부터 새로 시작합니다.

 

서비스 워커의 마지막 생명주기 fetch(오프라인 전환할 때 동작) 은 대표적으로 발생하는 시기는 브라우저에서 새로고침을 누를때 입니다. 새로고침을 누르게 되면 온라인 상태에서는 필요한 파일을 서버에서 가져오고 오프라인 상태에서는 캐시에서 가져옵니다.

 

PWA가 오프라인 상태에서도 잘 동작하게 하려면 fetch 이벤트가 발생한 후에 pEvent에 들어있는 respondWidth()함수를 잘 활용합니다. 

 respondWidth()함수는 결과값을 준비할때까자ㅣ 네트워크 요청을 일시 정지합니다. 즉  respondWidth()함수에서 캐시나 모바일 기기에 임시로 저장한 데이터를 가져와서 처리할 수 있습니다.

 

위 소스는 오프라인일때 PWA가 실행되면 캐시에서 가져올 데이터를 caches.match()함수로 캐시 저장소에서 검색하고, 발견된 캐시(response)를 반환하도록 코드를 작성했습니다. 만약 캐시를 발견하지 못하면 fetch(pEvent.request)를 통해 네트워크를 요청합니다.

 

 

5. 크롬 개발자 도구로 최종확인

크롬개발자 도구(F12)를 실행하여 적용한 내용들을 확인해봅니다.

Application 탭 -> Manifest 내용을 확인하여 매니페스트에 설정한 대로 잘 적용되었는지 확인합니다.

서비스 워커는 Application탭에 Service Worker를 클릭하여 확인합니다.

Status 항목 오른쪽에 초록색 동그라미가 있다는것은 서비스워커가 정상적으로 동작하고 있다는 뜻입니다.

 

만약 서비스워커기록이 남아있어서 새로운 서비스 워커와 충돌한다면 반드시 서비스워커를 삭제해야합니다.

Application탭에서 Clear storage를 클릭 Clear site date 버튼을 눌러 메모리에 저장된 서비스 워커, 캐시, 스토리지 데이터베이스 정보가 모두 삭제됩니다.

 

내가 사용하는 웹브라우저가 서비스워커를 지원하는지 궁금하다면, 아래에 주소에 접속하여 확인 할 수 있습니다. 

https://mobilehtml5.org/tests/sw/

위 사이트는 서비스워커가 지원되지 않는 브라우저를 파악가능합니다.

 

 

만약 오프라인일 때 동작하는 상태를 확인하려면 Network탭 -> Online을 Offline으로 바꾸면 웹 브라우저가 인터넷 연결을 차단합니다.

오프라인으로 변경 후 F5 새로고침을 눌러 인터넷이 안될때 PWA 동작을 확인해봅니다.(Console 메시지 확인)

 

스크립트를 활영하여 PWA를 개발하기 위해 기본적인 틀을 학습해보았습니다. 

수고하셨습니다.

'WEB' 카테고리의 다른 글

[PWA] 뷰티파이 기초편  (1) 2020.10.28
[PWA] 뷰 vue.js 고급 기능  (0) 2020.10.26
[PWA] 뷰 vue.js 입문  (1) 2020.10.26
[PWA] 모던자바스크립트 ES6 입문  (1) 2020.10.23
[PWA] 프로그래시브 웹앱 입문  (0) 2020.10.23
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크