javascript - Crear aplicación React PWA ERROR: No registra un service worker que controle la página y start_url
Estoy intentando crear una aplicación web progresiva con Create React App, pero recibo un error cuando hago una prueba con Lighthouse. Mi PWA no es instalable, lo extraño es que tengo el mismo problema si uso la plantilla PWA oficial de CRA.
Intenté cambiar la URL de inicio al nombre de dominio de mi aplicación, pero no funciona
Obtengo este error:
Does not register a service worker that controls page and start_url
y
Web app manifest or service worker do not meet the installability requirements 1 reason
No entiendo por qué recibo este error porque he seguido exactamente la documentación
Aquí está mi configuración:
manifest.json
{
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#000000",
"prefer_related_applications": false,
"short_name": "test",
"name": "test",
"icons": [
{
"src": "icons/android/android-launchericon-512-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/android/android-launchericon-192-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/android/maskable_icon_x192.png",
"type": "image/png",
"sizes": "192x192",
"purpose": "any maskable"
}
]
}
trabajador-de-servicio.ts
import { clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'
import { registerRoute } from 'workbox-routing'
import { StaleWhileRevalidate } from 'workbox-strategies'
declare const self: ServiceWorkerGlobalScope
clientsClaim()
precacheAndRoute(self.__WB_MANIFEST)
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$')
registerRoute(
({ request, url }: { request: Request; url: URL }) => {
if (request.mode !== 'navigate') {
return false
}
if (url.pathname.startsWith('/_')) {
return false
}
if (url.pathname.match(fileExtensionRegexp)) {
return false
}
// Return true to signal that we want to use the handler.
return true
},
createHandlerBoundToURL(`${process.env.PUBLIC_URL}/index.html`)
)
registerRoute(
({ url }) =>
url.origin === self.location.origin && url.pathname.endsWith('.png'),
new StaleWhileRevalidate({
cacheName: 'images',
plugins: [
new ExpirationPlugin({ maxEntries: 50 }),
],
})
)
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
self.skipWaiting()
}
})
registroServiceWorker.ts
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
window.location.hostname === '[::1]' ||
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
)
type Config = {
onSuccess?: (registration: ServiceWorkerRegistration) => void
onUpdate?: (registration: ServiceWorkerRegistration) => void
}
export function register(config?: Config): void {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href)
if (publicUrl.origin !== window.location.origin) {
return
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`
if (isLocalhost) {
checkValidServiceWorker(swUrl, config)
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://cra.link/PWA'
)
})
} else {
registerValidSW(swUrl, config)
}
})
}
}
function registerValidSW(swUrl: string, config?: Config): void {
navigator.serviceWorker
.register(swUrl)
.then((registration) => {
registration.onupdatefound = () => {
const installingWorker = registration.installing
if (installingWorker == null) {
return
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://cra.link/PWA.'
)
if (config && config.onUpdate) {
config.onUpdate(registration)
}
} else {
console.log('Content is cached for offline use.')
if (config && config.onSuccess) {
config.onSuccess(registration)
}
}
}
}
}
})
.catch((error) => {
console.error('Error during service worker registration:', error)
})
}
function checkValidServiceWorker(swUrl: string, config?: Config): void {
fetch(swUrl, {
headers: { 'Service-Worker': 'script' },
})
.then((response) => {
const contentType = response.headers.get('content-type')
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
navigator.serviceWorker.ready.then((registration) => {
registration.unregister().then(() => {
window.location.reload()
})
})
} else {
registerValidSW(swUrl, config)
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
)
})
}
export function unregister(): void {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then((registration) => {
registration.unregister()
})
.catch((error) => {
console.error(error.message)
})
}
}
app.tsx
serviceWorkerRegistration.unregister()
versión de Workbox: 6.1.5
Respuesta #1
¡Olvidé registrar el service worker, gracias!
Yo cambio
serviceWorkerRegistration.unregister()
a
serviceWorkerRegistration.register()
