From 486f236c1e96134c0ee8021ff5d04e93fe819e75 Mon Sep 17 00:00:00 2001 From: Ahad Birang Date: Wed, 29 Jun 2022 18:23:40 +0200 Subject: [PATCH] feat(service-worker): inject registration script to all pages (#299) --- src/prerender.ts | 12 ++++++-- src/presets/service-worker.ts | 52 +++++++++++++++++------------------ src/types/nitro.ts | 5 ++++ 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/src/prerender.ts b/src/prerender.ts index fd18a0bf44..873fb3da51 100644 --- a/src/prerender.ts +++ b/src/prerender.ts @@ -4,7 +4,7 @@ import { parseURL, withBase } from 'ufo' import chalk from 'chalk' import { createNitro } from './nitro' import { build } from './build' -import type { Nitro, PrerenderRoute } from './types' +import type { Nitro, PrerenderGenerateRoute, PrerenderRoute } from './types' import { writeFile } from './utils' const allowedExtensions = new Set(['', '.json']) @@ -43,13 +43,13 @@ export async function prerender (nitro: Nitro) { const generateRoute = async (route: string) => { const start = Date.now() - // Check if we should render routee + // Check if we should render route if (!canPrerender(route)) { return } generatedRoutes.add(route) routes.delete(route) // Create result object - const _route: PrerenderRoute = { route } + const _route: PrerenderGenerateRoute = { route } // Fetch the route const res = await (localFetch(withBase(route, nitro.options.baseURL), { headers: { 'X-Nitro-Prerender': route } }) as ReturnType) @@ -64,6 +64,12 @@ export async function prerender (nitro: Nitro) { const isImplicitHTML = !route.endsWith('.html') && (res.headers.get('content-type') || '').includes('html') const routeWithIndex = route.endsWith('/') ? route + 'index' : route _route.fileName = isImplicitHTML ? route + '/index.html' : routeWithIndex + + await nitro.hooks.callHook('prerender:generate', _route, nitro) + + // Check if route skipped by hook + if (_route.skip) { return } + const filePath = join(nitro.options.output.publicDir, _route.fileName) await writeFile(filePath, _route.contents) diff --git a/src/presets/service-worker.ts b/src/presets/service-worker.ts index c04557b736..f1f01ca42d 100644 --- a/src/presets/service-worker.ts +++ b/src/presets/service-worker.ts @@ -4,16 +4,26 @@ import { joinURL } from 'ufo' import { defineNitroPreset } from '../preset' import type { Nitro } from '../types' -// TODO -// const scriptTemplate = (baseURL = '/') => ` -// -// ` +const scriptTemplate = (baseURL = '/') => ` + +` const htmlTemplate = (baseURL = '/') => ` @@ -21,24 +31,8 @@ const htmlTemplate = (baseURL = '/') => ` - + ${scriptTemplate(baseURL)} - Initializing nitro service worker... @@ -55,6 +49,10 @@ export const serviceWorker = defineNitroPreset(() => { preview: 'npx serve ./public' }, hooks: { + 'prerender:generate' (route, nitro) { + const script = scriptTemplate(nitro.options.baseURL) + route.contents = route.contents.replace('', `${script}\n`) + }, async 'compiled' (nitro: Nitro) { // Write sw.js file await fsp.writeFile(resolve(nitro.options.output.publicDir, 'sw.js'), `self.importScripts('${joinURL(nitro.options.baseURL, 'server/index.mjs')}');`, 'utf8') diff --git a/src/types/nitro.ts b/src/types/nitro.ts index 3cc88dbb6e..9d547089e4 100644 --- a/src/types/nitro.ts +++ b/src/types/nitro.ts @@ -32,6 +32,10 @@ export interface PrerenderRoute { generateTimeMS?: number } +export interface PrerenderGenerateRoute extends PrerenderRoute { + skip?: boolean +} + type HookResult = void | Promise export interface NitroHooks { 'rollup:before': (nitro: Nitro) => HookResult @@ -39,6 +43,7 @@ export interface NitroHooks { 'dev:reload': () => HookResult 'close': () => HookResult 'prerender:route': (route: PrerenderRoute) => HookResult + 'prerender:generate': (route: PrerenderGenerateRoute, nitro: Nitro) => HookResult } type CustomDriverName = string & { _custom?: any }