Angular5 PWA(Service Workers)无法刷新,如何推送新版本?
Hey there, let's work through this PWA update headache you're dealing with. I totally get why you don't want to mess with the auto-generated sw.js—that's a recipe for unexpected bugs. Here's how to handle version pushes and take control of your app shell's lifecycle without touching the core Service Worker files:
1. Leverage Angular's Built-in SwUpdate Service
ng-cli 1.6+ integrates with @angular/service-worker, which provides the SwUpdate service specifically for managing updates. This is the official, supported way to handle version checks and activation—no manual sw.js edits needed.
Step 1: Set Up the Service
First, make sure your project is already configured for Service Workers (you probably have this done, but double-check):
- In
angular.json, ensureprojects.your-project-name.architect.build.options.serviceWorkeris set totrue - Your
index.htmlshould have the auto-generated Service Worker registration snippet (ng-cli adds this when you enable PWA support)
Step 2: Implement Version Detection & Update Flow
Create a service or add logic to your root component to listen for updates and prompt users:
import { Component, OnInit } from '@angular/core'; import { SwUpdate } from '@angular/service-worker'; @Component({ selector: 'app-root', templateUrl: './app.component.html' }) export class AppComponent implements OnInit { constructor(private swUpdate: SwUpdate) {} ngOnInit(): void { // Listen for when a new version becomes available this.swUpdate.available.subscribe((event) => { if (confirm('A new version of the app is ready! Would you like to refresh to update?')) { // Activate the new version and reload the page this.swUpdate.activateUpdate().then(() => { window.location.reload(); }); } }); // Optional: Check for updates on app load this.checkForUpdates(); } // Add a manual check (e.g., tie this to a "Check for Updates" button) checkForUpdates(): void { this.swUpdate.checkForUpdate() .catch(err => console.error('Failed to check for updates:', err)); } }
2. How Version Pushes Work (No Manual sw.js Edits!)
When you run ng build --prod, ng-cli generates an ngsw.json file that contains hashes of all your app's assets. The Service Worker uses this file to compare cached assets with the latest version on the server.
- When you deploy a new build, the
ngsw.jsonwill have new hashes for changed files. - The
SwUpdateservice will detect this change and trigger theavailableevent. - You don't need to modify
sw.js—ng-cli regenerates it correctly on each build.
3. Fix the "Can't Refresh After First Load" Issue
This usually happens because your server is caching sw.js or ngsw.json, so the client never sees the new version. Fix this by configuring your server to not cache these two files:
Example Nginx Configuration
location /ngsw.json { add_header Cache-Control "no-cache, no-store, must-revalidate"; } location /sw.js { add_header Cache-Control "no-cache, no-store, must-revalidate"; }
Example Apache Configuration
<Files "ngsw.json"> Header set Cache-Control "no-cache, no-store, must-revalidate" </Files> <Files "sw.js"> Header set Cache-Control "no-cache, no-store, must-revalidate" </Files>
4. Control App Shell Installation
The Service Worker automatically caches your app shell on first load. For updates, you're in full control:
- The
availableevent lets you decide when to notify the user activateUpdate()only applies the new version when you call it (after user confirmation, for example)- No need to manually manage cache entries—Angular's service worker handles that for you
内容的提问来源于stack exchange,提问作者Juan Sánchez

