improve service worker asset precaching and offline page

This commit is contained in:
keyan 2023-07-28 10:57:12 -05:00
parent b468b71e09
commit 688d67a0d6
5 changed files with 39 additions and 29 deletions

View File

@ -137,7 +137,7 @@ module.exports = withPlausibleProxy()({
]
},
webpack: (config, { isServer }) => {
if (isServer && isProd) {
if (isServer) {
generatePrecacheManifest()
config.plugins.push(
new InjectManifest({

View File

@ -1,12 +1,12 @@
import Image from 'react-bootstrap/Image'
import { StaticLayout } from '../components/layout'
import styles from '../styles/404.module.css'
import styles from '../styles/error.module.css'
export default function offline () {
return (
<StaticLayout>
<Image width='500' height='376' src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/falling.gif`} fluid />
<h1 className={styles.fourZeroFour}><span>Offline</span></h1>
<Image width='499' height='293' className='rounded-1 shadow-sm' src={`${process.env.NEXT_PUBLIC_ASSET_PREFIX}/waiting.gif`} fluid />
<h1 className={styles.status}><span>Offline</span></h1>
</StaticLayout>
)
}

BIN
public/waiting.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

13
styles/error.module.css Normal file
View File

@ -0,0 +1,13 @@
.status {
font-family: 'lightning';
font-size: 96px;
display: flex;
justify-content: space-evenly;
align-items: center;
margin-top: 1rem;
width: 100%;
}
.describe {
font-size: 24px;
}

View File

@ -1,8 +1,10 @@
const crypto = require('crypto')
const fs = require('fs')
const path = require('path')
const { createHash } = require('crypto')
const { readdirSync, readFileSync, statSync, writeFileSync } = require('fs')
const { join } = require('path')
const getRevision = filePath => crypto.createHash('md5').update(fs.readFileSync(filePath)).digest('hex')
const getRevision = filePath => createHash('md5').update(readFileSync(filePath)).digest('hex')
const walkSync = dir => readdirSync(dir, { withFileTypes: true }).flatMap(file =>
file.isDirectory() ? walkSync(join(dir, file.name)) : join(dir, file.name))
function formatBytes (bytes, decimals = 2) {
if (bytes === 0) {
@ -28,36 +30,31 @@ function generatePrecacheManifest () {
size += s
}
const staticDir = path.join(__dirname, '../public')
const staticFiles = fs.readdirSync(staticDir)
const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|webmanifest)$/, /^darkmode\.js$/].some(m => m.test(f))
const staticDir = join(__dirname, '../public')
const staticFiles = walkSync(staticDir)
console.log(staticFiles)
const staticMatch = f => [/\.(gif|jpe?g|ico|png|ttf|woff|woff2|webmanifest)$/].some(m => m.test(f))
staticFiles.filter(staticMatch).forEach(file => {
const filePath = path.join(staticDir, file)
const stats = fs.statSync(filePath)
if (stats.isFile()) {
addToManifest(filePath, '/' + file, stats.size)
}
const stats = statSync(file)
addToManifest(file, file.slice(staticDir.length), stats.size)
})
const pagesDir = path.join(__dirname, '../pages')
const pagesDir = join(__dirname, '../pages')
const precacheURLs = ['/offline']
const pagesFiles = fs.readdirSync(pagesDir)
const fileToUrl = f => '/' + f.replace(/\.js$/, '')
const pagesFiles = walkSync(pagesDir)
const fileToUrl = f => f.slice(pagesDir.length).replace(/\.js$/, '')
const pageMatch = f => precacheURLs.some(url => fileToUrl(f) === url)
pagesFiles.filter(pageMatch).forEach(file => {
const filePath = path.join(pagesDir, file)
const stats = fs.statSync(filePath)
if (stats.isFile()) {
// This is not ideal since dependencies of the pages may have changed
// but we would still generate the same revision ...
// The ideal solution would be to create a revision from the file generated by webpack
// in .next/server/pages but the file may not exist yet when we run this script
addToManifest(filePath, fileToUrl(file), stats.size)
}
const stats = statSync(file)
// This is not ideal since dependencies of the pages may have changed
// but we would still generate the same revision ...
// The ideal solution would be to create a revision from the file generated by webpack
// in .next/server/pages but the file may not exist yet when we run this script
addToManifest(file, fileToUrl(file), stats.size)
})
const output = 'sw/precache-manifest.json'
fs.writeFileSync(output, JSON.stringify(manifest, null, 2))
writeFileSync(output, JSON.stringify(manifest, null, 2))
console.log(`Created precache manifest at ${output}. Cache will include ${manifest.length} URLs with a size of ${formatBytes(size)}.`)
}