PWA (Progressive Web App)
Angular에서는 PWA를 매우 쉽게 적용할 수 있습니다. Cli에서 단순히 추가만 하면 알아서 필요한 요소들이 모두 설정되기 때문입니다.
이번 시간은 생성된 프로젝트에 PWA를 적용하고 작동여부 확인 테스트까지 진행해보겠습니다.
프로젝트 생성
먼저 프로젝트를 하나 생성합니다. 기존 프로젝트가 있으면 이 과정을 스킵해도 됩니다.
ng new project-pwa
pwa 추가
생성된 프로젝트에 아래와 같이 pwa를 추가합니다. –project 옵션 뒤에 프로젝트 명을 붙입니다.
ng add @angular/pwa --project [project-pwa]
확인
정상적으로 추가가 되었으면 아래의 파일을 확인합니다. 아래의 파일이 모두 확인되면 이미 pwa가 프로젝트에 적용된 것입니다.
- ngsw-config.json 파일 확인
- angular.json의 빌드 정보에 “serviceWorker”: true 확인
시작 모듈 확인
프로젝트 최초 시작 모듈 (기본으로 AppModule로 되어 있음)을 확인하여 아래와 같거나 유사한 코드가 있는지 확인합니다.
버전에 따라 다를 수 있으므로 만일 없으면 아래와 같이 추가하여야 합니다.
import { ServiceWorkerModule } from '@angular/service-worker';
@NgModule({
declarations: [],
imports: [
ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
],
providers: [],
})
export class AppModule { }
테스트 코드 작성하기 - component에서 버전업 체크 코드 넣기
최초로 로딩되는 component에 버전업 체크 코드를 넣어 앱의 버전이 변경되었을 때 이를 감지하는지 확인합니다.
import { Component, OnInit } from '@angular/core';
import { SwUpdate } from '@angular/service-worker';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
updateMessage: string;
constructor(
private swUpdate: SwUpdate
) {
}
ngOnInit() {
if ('serviceWorker' in navigator) {
console.log('service worker!!!!!!!!!!!!!');
if (this.swUpdate.isEnabled) {
this.swUpdate.available.subscribe(() => {
if (confirm('New version available. Load New Version?')) {
window.location.reload(); // 재시작하면 캐시된 데이터를 버리고 새 버전의 코드를 불러와 적용한다.
}
});
}
}
else {
console.log('service worker is not ready');
}
}
}
빌드
빌드는 환경에 따라 기존과 동일하게 빌드합니다.
ng build --prod
테스트
아래의 과정대로 테스트를 진행합니다.
이 테스트에서 유의할 점은 수정한 코드를 업로드한다고 즉시 인식하지 않는다는 점입니다.
이는 Angular의 정책상 적용 시간에 유예를 준 것인데 이를 수정하려면 pwa 관련 코드에서 SwUpdate 부분을 수정하면 됩니다.
- http-server로 가상 서버나 실제 서버를 띄워 application 실행
- 빌드된 코드 업로드
- 브라우저에서 확인
- 코드 또는 캐시된 데이터를 수정하고 재빌드 후 업로드
- 브라우저 reload
- 몇 초 이내에 새 버전 업로드 확인 여부
- yes를 클릭하면 업데이트됨을 확인
캐시 데이터 수정
캐시 데이터를 직접 수정할 수도 있습니다.
ngsw-config.json의 external을 수정하면 되는데 원하는 캐시데이터를 추가하거나 삭제하면 됩니다.
"external": {
"urls": [
{"url": "https://fonts.googleapis.com/..."},
{"url": "https://fonts.gstatic.com/s/..."}
]
}
캐시 금지
반대로 아래와 같이 캐시 금지를 적용할 수도 있습니다.
{
"name": "offline",
"urls": { "https://mysite.com/data.json": {"match": "prefix"}},
"cache": {
"optimizeFor": "freshness",
"maxAgeMs": 360000000,
"maxEntries": 1,
"strategy": "lru"
}
}
캐시 구분
- app: html, css, js, ts, favicon등 어플리케이션에 포함되는 파일
- assets: assets 폴더의 파일이나 필요할 때만 로드되는 파일
mode 구분
- lazy: 필요할 때만 로드되는 파일의 모드는 lazy로 설정합니다.
- prefetch: 한번만 request합니다. update는 prefeach로 설정하는 것이 좋습니다.
댓글남기기