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', () => {
it('installs a ServiceWorker', () => {
cy.visit('/', { serviceWorker: true })
.get('#swap-page')
.wait('@NotInstalled', { timeout: 20000 })
.window({ timeout: 20000 })
// This is emitted after caching the entry file, which takes some time to load.
.wait('@NotInstalled', { timeout: 60000 })
.window()
.and((win) => {
expect(win.navigator.serviceWorker.controller?.state).to.equal('activated')
})
......
......@@ -3,12 +3,11 @@ import 'workbox-precaching' // defines __WB_MANIFEST
import { clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { precacheAndRoute } from 'workbox-precaching'
import { PrecacheEntry } from 'workbox-precaching/_types'
import { registerRoute, Route } from 'workbox-routing'
import { CacheFirst } from 'workbox-strategies'
import { DocumentRoute } from './document'
import { toURL } from './utils'
import { groupEntries } from './utils'
declare const self: ServiceWorkerGlobalScope
......@@ -19,31 +18,20 @@ self.skipWaiting()
// This must be done before setting up workbox-precaching, so that it takes precedence.
registerRoute(new DocumentRoute())
// Splits entries into assets, which are loaded on-demand; and entries, which are precached.
// Effectively, this precaches the document, and caches all other assets on-demand.
const { assets, entries } = self.__WB_MANIFEST.reduce<{ assets: string[]; entries: PrecacheEntry[] }>(
({ assets, entries }, entry) => {
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: [] }
)
// Splits entries into:
// - mediaURLs: loaded on-demand
// - precacheEntries
const { mediaURLs, precacheEntries } = groupEntries(self.__WB_MANIFEST)
// Registers the assets' routes for on-demand caching.
registerRoute(
new Route(
({ url }) => assets.includes('.' + url.pathname),
({ url }) => mediaURLs.includes('.' + url.pathname),
new CacheFirst({
cacheName: 'assets',
cacheName: 'media',
plugins: [new ExpirationPlugin({ maxEntries: 16 })],
})
)
)
// 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() {
)
}
export function toURL(entry: string | PrecacheEntry): string {
return typeof entry === 'string' ? entry : entry.url
type GroupedEntries = { mediaURLs: string[]; precacheEntries: PrecacheEntry[] }
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