Angular 6을 사용하여 PWA 구축
게시 됨: 2022-03-10 이 자습서에서는 최신 Angular 6을 사용하여 PWA를 만드는 핵심 원칙을 구현하여 PWA를 빌드합니다. JSON API를 사용하는 프런트 엔드 웹 애플리케이션을 만드는 것으로 시작하겠습니다. 이 문제를 위해 Angular HttpClient
모듈을 사용하여 Simplified JavaScript Jargon GitHub 리포지토리에서 생성된 정적으로 JSON API에 HTTP 요청을 보냅니다. 또한 Angular Material 패키지를 통해 UI를 빌드하기 위해 Material Design을 사용할 것입니다.
다음으로 Chrome DevTools의 "감사" 패널(Lighthouse)을 사용하여 PWA의 핵심 원칙에 따라 웹 애플리케이션을 분석합니다. 마지막으로 Lighthouse 보고서의 "프로그레시브 웹 앱" 섹션에 따라 PWA 기능을 설명하고 웹 애플리케이션에 추가합니다.
PWA 구현을 시작하기 전에 먼저 PWA와 Lighthouse를 소개하겠습니다.
추천 자료 : 네이티브 및 PWA: 도전자가 아닌 선택!
PWA가 무엇입니까?
프로그레시브 웹 앱 또는 PWA는 사용자에게 앱과 같은 경험을 제공하는 기능 세트(네이티브 앱과 유사)가 있는 웹 애플리케이션입니다. PWA는 다음에 보게 될 일련의 필수 요구 사항을 충족해야 합니다. PWA는 기본 앱과 유사하지만 URL을 통해 웹 서버에서 배포 및 액세스할 수 있으므로 앱 스토어를 거칠 필요가 없습니다.
PWA는 다음과 같아야 합니다.
- 프로그레시브
브라우저 선택에 관계없이 모든 사용자가 사용할 수 있습니다. 핵심 원칙으로 점진적인 향상을 기반으로 구축되었기 때문입니다. - 반응형
모든 폼 팩터, 데스크탑, 모바일, 태블릿 또는 다음 제품에 적합합니다. - 연결 독립
서비스 작업자가 오프라인 또는 저품질 네트워크에서 작업하도록 향상되었습니다. - 앱 같은
앱 셸 모델을 사용하여 앱 스타일 탐색 및 상호 작용을 제공합니다. - 신선한
서비스 워커 업데이트 프로세스 덕분에 항상 최신 상태로 유지됩니다. - 안전한
스누핑을 방지하고 콘텐츠가 변조되지 않았는지 확인하기 위해 HTTPS를 통해 제공됩니다. - 발견 가능
W3C 매니페스트 및 검색 엔진에서 찾을 수 있는 서비스 작업자 등록 범위 덕분에 "응용 프로그램"으로 식별할 수 있습니다. - 재참여 가능
푸시 알림과 같은 기능을 통해 쉽게 재참여할 수 있습니다. - 설치 가능
사용자가 번거로운 앱 스토어 없이 홈 화면에서 가장 유용하다고 생각하는 앱을 "보관"할 수 있습니다. - 연결 가능
URL을 통해 쉽게 공유하고 복잡한 설치가 필요하지 않습니다.
등대를 소개합니다
Lighthouse는 접근성 성능, SEO, 모범 사례 및 PWA 기능에 대해 웹 사이트 및 애플리케이션을 감사하는 데 사용할 수 있는 Google에서 만든 오픈 소스 감사 도구입니다.
Node.js의 모듈 또는 CLI 도구로 Chrome DevTools의 감사 탭에서 Lighthouse에 액세스할 수 있습니다. URL을 제공한 다음 기본적으로 웹 응용 프로그램을 개선할 수 있는 방법에 대한 제안인 감사 결과가 포함된 보고서를 제공하는 감사를 실행하여 Lighthouse를 사용할 수 있습니다.
Angular CLI v6 설치 및 프로젝트 생성
이 섹션에서는 최신 버전의 Angular CLI를 설치한 다음 이를 사용하여 새 Angular 6 프로젝트를 생성합니다.
Angular CLI에는 Node.js >= 8.9 이상 이 필요하므로 먼저 다음 명령을 실행하여 필요한 버전이 설치되어 있는지 확인하십시오.
$ node -v
Node.js가 설치되어 있지 않은 경우 공식 Node 다운로드 페이지로 이동하여 시스템의 Node 바이너리를 다운로드할 수 있습니다.
이제 다음을 실행하여 최신 버전의 Angular CLI를 설치할 수 있습니다.
$ npm install -g @angular/cli
참고 : npm 구성에 따라 패키지를 전역으로 설치하려면 _sudo_
를 추가해야 할 수도 있습니다.
터미널에서 다음 명령을 실행하여 Angular 6 프로젝트를 생성할 수 있습니다.
$ ng new pwademo
이렇게 하면 다음과 같은 구조의 프로젝트가 생성됩니다.
수행되는 대부분의 작업은 애플리케이션의 소스 코드가 포함된 src/
폴더 안에 있습니다.
Angular 애플리케이션 만들기
프로젝트를 생성한 후 JSON API를 사용하고 홈 페이지에 항목을 표시하는 웹 애플리케이션을 빌드합니다. HTTP 요청을 보내는 데 HttpClient 서비스를 사용하고 UI를 빌드하는 데 Angular Material을 사용합니다.
앵귤러 머티리얼 추가하기
Angular CLI v6과 새로운 ng add 명령 덕분에 프로젝트에 Angular Material을 추가하는 것은 단 하나의 명령입니다. 터미널에서 다음 명령을 실행하기만 하면 됩니다.
$ cd pwademo $ ng add @angular/material
스크린샷에서 명령이 npm에서 필요한 패키지를 설치하고 이전에 수동 업데이트가 필요했던 프로젝트에서 Angular Material을 설정하기 위한 많은 파일을 업데이트하는 것을 볼 수 있습니다.
HttpClient
설정 및 JSON API 사용
이제 HTTP 요청을 보내기 위해 HttpClient
를 사용하도록 Angular 프로젝트를 설정해 보겠습니다. 먼저 src/app/app.module.ts
파일의 기본 애플리케이션 모듈에서 HttpClientModule
모듈을 가져와야 합니다.
/*...*/ import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [ AppComponent ], imports: [ /*...*/ HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
그게 다야 이제 주 모듈에 속한 모든 구성 요소 또는 서비스에서 HttpClient
를 주입하고 사용할 수 있습니다.
데모 목적으로 Simplified JavaScript Jargon GitHub 리포지토리에서 정적으로 생성된 JSON API를 사용합니다. 다른 리소스를 사용하는 경우 동일한 출처 정책 으로 인해 브라우저가 원격 리소스 읽기를 허용하지 않도록 CORS를 활성화했는지 확인하십시오.
API와 인터페이스하는 서비스를 만들어 봅시다. 프로젝트 폴더 내에서 다음을 실행합니다.
$ ng g service api
그러면 src/app/api.service.ts
파일에 ApiService
라는 서비스가 생성됩니다.
이제 src/app/api.service.ts
파일을 열고 다음 변경 사항을 반영하도록 업데이트합니다.
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; export interface Item{ name: string; description: string; url: string; html: string; markdown: string; } @Injectable({ providedIn: 'root' }) export class ApiService { private dataURL: string = "https://www.techiediaries.com/api/data.json"; constructor(private httpClient: HttpClient) {} fetch(): Observable<Item[]>{ return <Observable<Item[]>this.httpClient.get(this.dataURL); } }
먼저 HttpClient
및 Observable
클래스를 가져온 다음 생성자에 httpClient
로 HttpClient
를 주입하고 HttpClient
의 get()
메서드를 호출하는 fetch()
메서드를 추가했습니다(JSON 끝점에 HTTP GET 요청 보내기). 그리고 Observable을 반환합니다. 나중에 구독할 수 있습니다.
또한 반환된 JSON 데이터의 단일 항목을 나타내는 Item
인터페이스도 선언했습니다.
다음으로 응용 프로그램 구성 요소에서 이 서비스를 가져옵니다. src/app/app.component.ts
파일을 열고 다음을 추가합니다.
import { Component, OnInit } from '@angular/core'; import { ApiService } from './api.service'; import { Item } from './api.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit{ title = 'pwademo'; items: Array<Item>; constructor(private apiService: ApiService){ } ngOnInit(){ this.fetchData(); } fetchData(){ this.apiService.fetch().subscribe((data: Array<Item>)=>{ console.log(data); this.items = data; }, (err)=>{ console.log(err); }); } }
이전에 생성한 ApiService
를 가져오고 apiService
로 주입하고 JSON 데이터의 단일 항목을 나타내는 Item
클래스도 가져오고 가져온 항목을 보유할 Array<Item>
유형의 items
변수를 선언합니다.
다음으로 Observable을 반환하는 ApiService
에서 정의한 fetch()
메서드를 호출하는 fetchData()
메서드를 추가합니다. JSON 끝점에 GET 요청을 보내고 마침내 items
배열에 할당한 응답 데이터를 얻기 위해 이 관찰 가능 항목을 구독하기만 하면 됩니다.
ngOnInit()
수명 주기 이벤트에서 fetchData()
메서드를 호출하므로 AppComponent
구성 요소가 초기화되면 호출됩니다.
애플리케이션 UI 추가
우리의 애플리케이션 UI는 Angular Material로 생성될 페이지의 뼈대와 탐색 모음으로 구성될 것입니다.
Angular Material 구성 요소를 사용하기 전에 해당 모듈을 가져와야 합니다. 각 Material 구성 요소는 자체 모듈에 속합니다.
src/app/app.module.ts
파일을 열고 다음 가져오기를 추가합니다.
/*...*/ import { MatToolbarModule } from '@angular/material/toolbar'; import { MatCardModule } from '@angular/material/card'; import { MatButtonModule } from '@angular/material/button'; @NgModule({ declarations: [ AppComponent ], imports: [ /*...*/ MatToolbarModule, MatCardModule, MatButtonModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
도구 모음, 카드 및 버튼 구성 요소에 대한 모듈을 가져오고 AppModule
의 가져오기 배열에 추가합니다.
다음으로 src/app/app.component.html
파일을 열고 그 안에 있는 내용을 삭제하고 다음을 추가합니다.
<mat-toolbar color="primary"> <mat-toolbar-row> <span>JS-jargon</span> </mat-toolbar-row> </mat-toolbar> <main> <mat-card *ngFor="let item of items"> <mat-card-header> <mat-card-title>{{item.name}}</mat-card-title> </mat-card-header> <mat-card-content> {{item.description}} </mat-card-content> <mat-card-actions> <a mat-raised-button href="{{item.url}}" color="primary">More</a> </mat-card-actions> </mat-card> </main>
Material 구성 요소를 사용하여 UI를 만듭니다. <mat-toolbar>
구성 요소는 재료 도구 모음을 만드는 데 사용되며 <mat-card>
구성 요소는 재료 카드 등을 만드는 데 사용됩니다.
구성 요소가 초기화될 때 fetchData()
메서드에 의해 채워지는 items
배열을 반복하고 항목을 재료 카드로 표시합니다. 각 카드에는 이름, 설명 및 추가 정보 링크가 포함되어 있습니다(링크는 mat-raised-button
지시문을 사용하여 Material 버튼으로 스타일 지정됨).
다음은 애플리케이션의 스크린샷입니다.
프로덕션용 애플리케이션 빌드
일반적으로 애플리케이션에서 PWA 기능을 확인할 때 대부분의 PWA 기능이 개발 단계에 추가되지 않기 때문에 먼저 프로덕션용으로 빌드해야 합니다. 예를 들어, 주기적으로 파일을 업데이트해야 하므로 개발 단계에서 서비스 워커와 캐싱을 활성화하고 싶지 않습니다.
다음 명령을 사용하여 프로덕션용 애플리케이션을 빌드해 보겠습니다.
$ ng build --prod
프로덕션 빌드는 dist/pwademo
폴더에서 사용할 수 있습니다. 우리는 그것을 제공하기 위해 http-server
와 같은 도구를 사용할 수 있습니다.
먼저 다음 명령을 사용하여 http-server
를 설치합니다.
$ npm i -g http-server
그런 다음 다음 명령을 사용하여 실행할 수 있습니다.
$ cd dist/pwademo $ http-server -o
-o
옵션은 시스템의 기본 브라우저를 자동으로 열고 웹 애플리케이션을 사용할 수 있는 https://127.0.0.1:8080/
주소로 이동합니다.
Lighthouse를 사용하여 애플리케이션 분석
이제 Lighthouse를 사용하여 애플리케이션을 분석해 보겠습니다. 먼저 Chrome을 실행하고 애플리케이션 주소 https://127.0.0.1:8080/
을 방문합니다.
그런 다음 개발자 도구 를 열거나 Ctrl + Shift + I 을 누르고 감사 패널을 클릭합니다.
모바일 환경을 에뮬레이트하려면 데스크톱 대신 모바일 로 에뮬레이션 을 설정해야 합니다. 그런 다음 감사 수행… 파란색 버튼을 클릭합니다. 웹 애플리케이션에 대해 수행할 감사 유형을 선택해야 하는 대화 상자가 열립니다. Progressive Web App 을 제외한 모든 유형의 선택을 취소하고 감사 실행 버튼을 클릭합니다.
Lighthouse가 보고서를 생성할 때까지 기다리십시오. 다음은 이 단계의 결과 스크린샷입니다.
Lighthouse는 PWA 체크리스트에 지정된 프로그레시브 웹 앱의 측면을 검증하는 일련의 검사를 수행합니다. 일부 감사를 통과했기 때문에 초기 점수는 36 ⁄ 100 입니다.
우리 애플리케이션은 주로 PWA의 핵심 측면인 서비스 워커 , 프로그레시브 향상 , HTTPS 및 웹 앱 매니페스트 와 관련된 7개의 실패한 감사를 가지고 있습니다.
서비스 워커 등록
처음 두 개의 실패한 감사("서비스 워커를 등록하지 않음" 및 "오프라인 시 200으로 응답하지 않음")는 서비스 워커 및 캐싱과 관련이 있습니다. 그렇다면 서비스 워커는 무엇일까요?
서비스 워커는 애플리케이션이 자산과 데이터를 캐시하기 위한 네트워크 요청을 가로채도록 하는 네트워크 프록시로 사용할 수 있는 최신 브라우저에서 사용할 수 있는 기능입니다. 이것은 오프라인 지원 및 푸시 알림 등과 같은 PWA 기능을 구현하는 데 사용할 수 있습니다.
이러한 감사를 통과하려면 서비스 워커를 등록하고 이를 사용하여 로컬에서 파일을 캐시하기만 하면 됩니다. 오프라인일 때 SW는 로컬에 캐시된 파일 버전을 반환해야 합니다. 나중에 하나의 CLI 명령으로 추가하는 방법을 살펴보겠습니다.
추천 자료 : 서비스 워커 만들기: 사례 연구
점진적 향상
세 번째 실패한 감사("JavaScript를 사용할 수 없을 때 대체 콘텐츠를 제공하지 않음")는 PWA의 필수 측면인 Progressive Enhancement 와 관련이 있으며 단순히 PWA가 다른 브라우저에서 실행되지만 다음과 같은 경우 고급 기능을 제공하는 기능을 나타냅니다. 그들은 사용할 수 있습니다. PE의 한 가지 간단한 예는 <noscript>
HTML 태그를 사용하는 것입니다. 이 태그는 활성화되지 않은 경우 JavaScript를 활성화하여 애플리케이션을 실행할 필요가 있음을 사용자에게 알립니다.
<noscript> Please enable JavaScript to run this application. </noscript>
HTTPS
네 번째 실패한 감사("HTTP 트래픽을 HTTPS로 리디렉션하지 않음")는 PWA의 핵심 측면이기도 한 HTTPS와 관련이 있습니다(서비스 작업자는 localhost를 제외한 보안 출처에서만 서비스를 제공할 수 있음). "HTTPS 사용" 감사 자체는 우리가 localhost를 감사하기 때문에 Lighthouse에 의해 통과된 것으로 간주되지만 실제 호스트를 사용하면 SSL 인증서가 필요합니다. Let's Encrypt, Cloudflare, Firebase 또는 Netlify 등과 같은 다양한 서비스에서 무료 SSL 인증서를 얻을 수 있습니다.
웹 앱 매니페스트
세 가지 실패한 감사("사용자에게 웹 앱을 설치하라는 메시지가 표시되지 않음", "사용자 정의 시작 화면에 대해 구성되지 않음" 및 "주소 표시줄이 브랜드 색상과 일치하지 않음")는 누락된 웹 앱 매니페스트 와 관련이 있습니다. PWA에 필요한 이름, 설명, 아이콘 및 기타 정보를 제공하는 JSON 형식의 파일입니다. 사용자가 앱 스토어를 거치지 않고 기본 앱처럼 홈 화면에 웹 앱을 설치할 수 있습니다.
웹 앱 매니페스트를 제공하고 rel
속성이 manifest
로 설정된 <link>
태그를 사용하여 index.html
파일에서 이를 참조해야 합니다. 하나의 CLI 명령으로 자동으로 수행하는 방법을 다음에서 살펴보겠습니다.
PWA 기능 구현
Angular CLI v6을 사용하면 기존 Angular 애플리케이션에 PWA 기능을 빠르게 추가할 수 있습니다. 프로젝트 루트의 터미널에서 다음 명령을 실행하기만 하면 애플리케이션을 PWA로 전환할 수 있습니다.
$ ng add @angular/pwa
이 명령은 다음과 같은 PWA 기능을 Angular 애플리케이션에 자동으로 추가합니다.
-
manifest.json
파일, -
src/assets/icons
폴더에 있는 다양한 크기의 아이콘, -
ngsw-worker.js
서비스 워커.
프로덕션 빌드가 포함된 dist/
폴더를 엽니다. 다양한 파일을 찾을 수 있지만 위에서 언급한 PWA 기능과 관련된 파일에 집중해 보겠습니다.
다음 내용으로 manifest.json
파일이 추가되었습니다.
{ "name": "pwademo", "short_name": "pwademo", "theme_color": "#1976d2", "background_color": "#fafafa", "display": "standalone", "scope": "/", "start_url": "/", "icons": [ { "src": "assets/icons/icon-72x72.png", "sizes": "72x72", "type": "image/png" }, { "src": "assets/icons/icon-96x96.png", "sizes": "96x96", "type": "image/png" }, { "src": "assets/icons/icon-128x128.png", "sizes": "128x128", "type": "image/png" }, { "src": "assets/icons/icon-144x144.png", "sizes": "144x144", "type": "image/png" }, { "src": "assets/icons/icon-152x152.png", "sizes": "152x152", "type": "image/png" }, { "src": "assets/icons/icon-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "assets/icons/icon-384x384.png", "sizes": "384x384", "type": "image/png" }, { "src": "assets/icons/icon-512x512.png", "sizes": "512x512", "type": "image/png" } ] }
보시다시피 추가된 manifest.json
파일에는 이름, 설명, start_url
등과 같이 PWA에 필요한 모든 정보가 있습니다.
assets/icons
폴더에도 자동으로 추가된 다양한 크기의 아이콘에 대한 링크인 manifest.json
파일입니다. 물론 PWA의 최종 버전을 빌드할 준비가 되면 해당 아이콘을 자신의 것으로 변경해야 합니다.
index.html
파일에서 manifest.json
파일은 다음을 사용하여 참조됩니다.
<link rel="manifest" href="manifest.json">
서비스 워커를 포함하는 ngsw-worker.js
파일도 자동으로 추가되었습니다. 이 서비스 워커를 설치하는 코드는 src/app/app.module.ts
파일에 자동으로 삽입됩니다.
... import { ServiceWorkerModule } from '@angular/service-worker'; @NgModule({ declarations: [ AppComponent ], imports: [ ... ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production }) ],
@angular/service-worker
는 ng add
명령으로 설치되고 pwademo/package.json
에 종속성으로 추가됩니다.
"dependencies": { ... "@angular/service-worker": "^6.1.0" }
서비스 워커 빌드 지원은 CLI에서도 활성화됩니다. angular.json
파일에 "serviceWorker": true
구성 옵션이 추가됩니다.
index.html
파일에서 값이 #1976d2
인 theme-color
에 대한 메타 태그가 추가됩니다( manifest.json
파일의 theme_color
값에도 해당).
<meta name="theme-color" content="#1976d2">
테마 색상은 주소 표시줄과 같은 UI 요소에 색조를 적용할 색상을 브라우저에 알려줍니다.
index.html
및 manifest.json
파일 모두에 테마 색상을 추가하면 주소 표시줄이 브랜드 색상과 일치하는 감사를 수정합니다.
서비스 워커 구성 파일
다른 파일 src/ngsw-config.json
이 프로젝트에 추가되지만 PWA의 필수 파일은 아닙니다. Angular 서비스 작업자가 캐시해야 하는 파일 및 데이터 URL과 캐시된 파일 및 데이터를 업데이트하는 방법을 지정할 수 있는 구성 파일입니다. 공식 문서에서 이 파일에 대한 모든 세부 정보를 찾을 수 있습니다.
참고 : 이 글을 쓰는 시점에서 최신 6.1.3 이전 ng add @angular/pwa
명령은 다음 오류와 함께 실패합니다. Path “/ngsw-config.json” already exists
하므로 지금은 @angular/cli
를 다운그레이드하는 것이 해결책입니다. 및 @angular/pwa
를 버전 6.0.8 로 변경합니다.
프로젝트에서 다음 명령을 실행하기만 하면 됩니다.
$ npm i @angular/[email protected] $ ng i @angular/[email protected] $ ng add @angular/pwa
이제 로컬에서 호스팅되는 로컬 PWA에 대해 감사를 다시 실행해 보겠습니다. 이것은 새로운 PWA 점수입니다:
Angular CLI는 Progressive Enhancement 섹션에서 언급한 JavaScript 폴백 코드를 자동으로 추가하지 않으므로 src/index.html
파일을 열고 추가합니다.
<noscript> Please enable JavaScript to run this application. </noscript>
그런 다음 애플리케이션을 다시 빌드하고 감사를 다시 실행합니다. 이제 결과는 다음과 같습니다.
HTTPS 리디렉션과 관련된 실패한 감사는 단 한 번뿐입니다. 애플리케이션을 호스팅하고 HTTP에서 HTTPS로 리디렉션을 구성해야 합니다.
이제 PWA의 호스팅 및 보안 버전에 대해 감사를 실행해 보겠습니다.
100 ⁄ 100 이라는 점수는 PWA의 모든 핵심 원칙을 성공적으로 구현했음을 의미합니다.
이 GitHub 리포지토리에서 이 데모 PWA의 최종 코드를 얻을 수 있습니다.
결론
이 튜토리얼에서는 간단한 Angular 애플리케이션을 구축하고 Angular CLI를 사용하여 PWA로 전환했습니다. 우리는 Google의 Lighthouse를 사용하여 PWA 기능에 대한 애플리케이션을 감사하고 오프라인 지원 및 푸시 알림을 추가하기 위한 서비스 워커 와 같은 PWA의 다양한 핵심 교리를 설명했습니다. 홈 화면에 추가 및 시작 화면 기능, Progressive Enhancement 및 HTTPS 를 활성화하기 위한 웹 매니페스트 파일 .
강조 표시된 다른 항목("수동으로 확인할 추가 항목" 섹션 아래)을 수동으로 확인해야 할 수도 있지만 Lighthouse에서 자동으로 확인하지는 않습니다. 이러한 검사는 Google의 기준 PWA 체크리스트에 필요합니다. PWA 점수에는 영향을 미치지 않지만 수동으로 확인하는 것이 중요합니다. 예를 들어, 사이트가 브라우저 간에 작동하는지 확인하고 각 페이지에 소셜 미디어에서 공유 가능성을 위해 중요한 URL이 있는지 확인해야 합니다.
PWA는 더 나은 인식 성능 및 접근성과 같은 다른 측면에 관한 것이므로 Lighthouse를 사용하여 이러한 측면에 대해 PWA(또는 일반 웹사이트)를 감사하고 필요에 따라 개선할 수도 있습니다.