Commit 3a82642f authored by Vignesh Mohankumar's avatar Vignesh Mohankumar Committed by GitHub

fix: update service worker to precache css/js files (#6486)

* fix: update service worker to precache css/js files

* add test

* move to utils

* working tests

* fixes

* lint

* change names

* lint

* change return type

* fix

* fix

* changes

* lint

* rename cache

* lint

* fix comments and remove string[] case

* string |

* Update src/serviceWorker/utils.ts
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>

---------
parent 2a50d6a1
...@@ -53,8 +53,9 @@ describe('Service Worker', () => { ...@@ -53,8 +53,9 @@ describe('Service Worker', () => {
it('installs a ServiceWorker', () => { it('installs a ServiceWorker', () => {
cy.visit('/', { serviceWorker: true }) cy.visit('/', { serviceWorker: true })
.get('#swap-page') .get('#swap-page')
.wait('@NotInstalled', { timeout: 20000 }) // This is emitted after caching the entry file, which takes some time to load.
.window({ timeout: 20000 }) .wait('@NotInstalled', { timeout: 60000 })
.window()
.and((win) => { .and((win) => {
expect(win.navigator.serviceWorker.controller?.state).to.equal('activated') expect(win.navigator.serviceWorker.controller?.state).to.equal('activated')
}) })
......
...@@ -3,12 +3,11 @@ import 'workbox-precaching' // defines __WB_MANIFEST ...@@ -3,12 +3,11 @@ import 'workbox-precaching' // defines __WB_MANIFEST
import { clientsClaim } from 'workbox-core' import { clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration' import { ExpirationPlugin } from 'workbox-expiration'
import { precacheAndRoute } from 'workbox-precaching' import { precacheAndRoute } from 'workbox-precaching'
import { PrecacheEntry } from 'workbox-precaching/_types'
import { registerRoute, Route } from 'workbox-routing' import { registerRoute, Route } from 'workbox-routing'
import { CacheFirst } from 'workbox-strategies' import { CacheFirst } from 'workbox-strategies'
import { DocumentRoute } from './document' import { DocumentRoute } from './document'
import { toURL } from './utils' import { groupEntries } from './utils'
declare const self: ServiceWorkerGlobalScope declare const self: ServiceWorkerGlobalScope
...@@ -19,31 +18,20 @@ self.skipWaiting() ...@@ -19,31 +18,20 @@ self.skipWaiting()
// This must be done before setting up workbox-precaching, so that it takes precedence. // This must be done before setting up workbox-precaching, so that it takes precedence.
registerRoute(new DocumentRoute()) registerRoute(new DocumentRoute())
// Splits entries into assets, which are loaded on-demand; and entries, which are precached. // Splits entries into:
// Effectively, this precaches the document, and caches all other assets on-demand. // - mediaURLs: loaded on-demand
const { assets, entries } = self.__WB_MANIFEST.reduce<{ assets: string[]; entries: PrecacheEntry[] }>( // - precacheEntries
({ assets, entries }, entry) => { const { mediaURLs, precacheEntries } = groupEntries(self.__WB_MANIFEST)
if (typeof entry === 'string') {
return { entries, assets: [...assets, entry] }
} else if (entry.revision) {
return { entries: [...entries, entry], assets }
} else {
return { entries, assets: [...assets, toURL(entry)] }
}
},
{ assets: [], entries: [] }
)
// Registers the assets' routes for on-demand caching.
registerRoute( registerRoute(
new Route( new Route(
({ url }) => assets.includes('.' + url.pathname), ({ url }) => mediaURLs.includes('.' + url.pathname),
new CacheFirst({ new CacheFirst({
cacheName: 'assets', cacheName: 'media',
plugins: [new ExpirationPlugin({ maxEntries: 16 })], plugins: [new ExpirationPlugin({ maxEntries: 16 })],
}) })
) )
) )
// Precaches entries and registers a default route to serve them. // Precaches entries and registers a default route to serve them.
precacheAndRoute(entries) precacheAndRoute(precacheEntries)
import { groupEntries } from './utils'
describe('groupEntries', () => {
test('splits resources into mediaURLs and precacheEntries', () => {
const resources = [
'./static/whitepaper.pdf',
{ url: './static/js/main.js', revision: 'abc123' },
{ url: './static/css/styles.css', revision: 'def456' },
{ url: './static/media/image.jpg', revision: 'ghi789' },
]
const result = groupEntries(resources)
expect(result).toEqual({
mediaURLs: ['./static/whitepaper.pdf', './static/media/image.jpg'],
precacheEntries: [
{ url: './static/js/main.js', revision: 'abc123' },
{ url: './static/css/styles.css', revision: 'def456' },
],
})
})
})
...@@ -16,6 +16,18 @@ export function isDevelopment() { ...@@ -16,6 +16,18 @@ export function isDevelopment() {
) )
} }
export function toURL(entry: string | PrecacheEntry): string { type GroupedEntries = { mediaURLs: string[]; precacheEntries: PrecacheEntry[] }
return typeof entry === 'string' ? entry : entry.url export function groupEntries(entries: (string | PrecacheEntry)[]): GroupedEntries {
return entries.reduce<GroupedEntries>(
({ mediaURLs, precacheEntries }, entry) => {
if (typeof entry === 'string') {
return { precacheEntries, mediaURLs: [...mediaURLs, entry] }
} else if (entry.url.includes('/media/')) {
return { precacheEntries, mediaURLs: [...mediaURLs, entry.url] }
} else {
return { precacheEntries: [...precacheEntries, entry], mediaURLs }
}
},
{ mediaURLs: [], precacheEntries: [] }
)
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment