Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(plugin-pwa): migrate pwa plugin
- Loading branch information
Showing
11 changed files
with
281 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
{ | ||
"name": "@vuepress/plugin-pwa", | ||
"version": "2.0.0-alpha.7", | ||
"description": "VuePress plugin - progressive web application", | ||
"keywords": [ | ||
"vuepress", | ||
"plugin", | ||
"pwa" | ||
], | ||
"homepage": "https://github.com/vuepress", | ||
"bugs": { | ||
"url": "https://github.com/vuepress/vuepress-next/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/vuepress/vuepress-next.git" | ||
}, | ||
"license": "MIT", | ||
"author": "meteorlxy", | ||
"main": "lib/index.js", | ||
"types": "lib/index.d.ts", | ||
"files": [ | ||
"lib", | ||
"styles" | ||
], | ||
"scripts": { | ||
"build": "tsc -b tsconfig.build.json", | ||
"clean": "rimraf lib *.tsbuildinfo" | ||
}, | ||
"dependencies": { | ||
"@vuepress/client": "2.0.0-alpha.7", | ||
"@vuepress/core": "2.0.0-alpha.7", | ||
"@vuepress/utils": "2.0.0-alpha.7", | ||
"mitt": "^2.1.0", | ||
"register-service-worker": "^1.7.2", | ||
"vue": "^3.0.4", | ||
"workbox-build": "^6.0.2" | ||
}, | ||
"devDependencies": { | ||
"@types/workbox-build": "^5.0.0" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import mitt from 'mitt' | ||
import { onMounted, provide } from 'vue' | ||
import { withBase } from '@vuepress/client' | ||
import type { ClientAppSetup } from '@vuepress/client' | ||
import { pwaEventSymbol } from './composables' | ||
import type { PwaEvent } from './composables' | ||
|
||
declare const __DEV__: boolean | ||
declare const __SSR__: boolean | ||
declare const __PWA_SW_FILENAME__: string | ||
|
||
const swFilename = __PWA_SW_FILENAME__ | ||
|
||
const clientAppSetup: ClientAppSetup = () => { | ||
if (__DEV__ || __SSR__ || !swFilename) return | ||
|
||
const log = (...args: any[]) => console.log('[@vuepress/plugin-pwa]', ...args) | ||
|
||
// create event emitter and provide it | ||
const event: PwaEvent = mitt() | ||
provide(pwaEventSymbol, event) | ||
|
||
onMounted(async () => { | ||
// lazy load register-service-worker | ||
const { register } = await import('register-service-worker') | ||
|
||
// Register service worker | ||
register(withBase(swFilename), { | ||
ready(registration) { | ||
log('Service worker is active.') | ||
event.emit('ready', registration) | ||
}, | ||
|
||
registered(registration) { | ||
log('Service worker has been registered.') | ||
event.emit('registered', registration) | ||
}, | ||
|
||
cached(registration) { | ||
log('Content has been cached for offline use.') | ||
event.emit('cached', registration) | ||
}, | ||
|
||
updatefound(registration) { | ||
log('New content is downloading.') | ||
event.emit('updatefound', registration) | ||
}, | ||
|
||
updated(registration) { | ||
log('New content is available, please refresh.') | ||
event.emit('updated', registration) | ||
}, | ||
|
||
offline() { | ||
log('No internet connection found. App is running in offline mode.') | ||
event.emit('offline') | ||
}, | ||
|
||
error(err) { | ||
log('Error during service worker registration:', err) | ||
event.emit('error', err) | ||
}, | ||
}) | ||
}) | ||
} | ||
|
||
export default clientAppSetup |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * from './usePwaEvent' | ||
export * from './useSkipWaiting' |
32 changes: 32 additions & 0 deletions
32
packages/@vuepress/plugin-pwa/src/composables/usePwaEvent.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import type { Emitter, Handler, WildcardHandler } from 'mitt' | ||
import { inject } from 'vue' | ||
import type { InjectionKey } from 'vue' | ||
|
||
export interface PwaEvent extends Emitter { | ||
on(type: 'ready', handler: Handler<ServiceWorkerRegistration>): void | ||
on(type: 'registered', handler: Handler<ServiceWorkerRegistration>): void | ||
on(type: 'cached', handler: Handler<ServiceWorkerRegistration>): void | ||
on(type: 'updatefound', handler: Handler<ServiceWorkerRegistration>): void | ||
on(type: 'updated', handler: Handler<ServiceWorkerRegistration>): void | ||
on(type: 'offline', handler: Handler<void>): void | ||
on(type: 'error', handler: Handler<Error>): void | ||
on(type: '*', handler: WildcardHandler): void | ||
emit(type: 'ready', event: ServiceWorkerRegistration): void | ||
emit(type: 'registered', event: ServiceWorkerRegistration): void | ||
emit(type: 'cached', event: ServiceWorkerRegistration): void | ||
emit(type: 'updatefound', event: ServiceWorkerRegistration): void | ||
emit(type: 'updated', event: ServiceWorkerRegistration): void | ||
emit(type: 'offline'): void | ||
emit(type: 'error', event: Error): void | ||
emit(type: '*', event?: any): void | ||
} | ||
|
||
export const pwaEventSymbol: InjectionKey<PwaEvent> = Symbol('pwaEvent') | ||
|
||
export const usePwaEvent = (): PwaEvent => { | ||
const pawEvent = inject(pwaEventSymbol) | ||
if (!pawEvent) { | ||
throw new Error('usePwaEvent() is called without provider.') | ||
} | ||
return pawEvent | ||
} |
17 changes: 17 additions & 0 deletions
17
packages/@vuepress/plugin-pwa/src/composables/useSkipWaiting.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/** | ||
* Call `skipWaiting()` inside current waiting worker | ||
*/ | ||
export const useSkipWaiting = ( | ||
registration: ServiceWorkerRegistration | ||
): void => { | ||
// get the waiting worker | ||
const worker = registration.waiting | ||
|
||
// if there is no waiting worker, return directly | ||
if (!worker) return | ||
|
||
// post SKIP_WAITING message to the waiting worker | ||
const channel = new MessageChannel() | ||
|
||
worker.postMessage({ type: 'SKIP_WAITING' }, [channel.port2]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import type { Plugin } from '@vuepress/core' | ||
import { logger, path, withSpinner } from '@vuepress/utils' | ||
import type { | ||
generateSW as GenerateSWFunc, | ||
GenerateSWConfig, | ||
} from 'workbox-build' | ||
|
||
/** | ||
* Options for @vuepress/plugin-pwa | ||
*/ | ||
export interface PwaPluginOptions | ||
extends Omit<GenerateSWConfig, 'swDest' | 'globDirectory'> { | ||
/** | ||
* Filename of the generated service worker file | ||
* | ||
* If you put it into a sub directory, the `scope` of service worker | ||
* might be affected | ||
* | ||
* @default 'service-worker.js' | ||
*/ | ||
serviceWorkerFilename?: string | ||
} | ||
|
||
const assetsExtensions = [ | ||
// basic | ||
'html', | ||
'js', | ||
'css', | ||
// images | ||
'png', | ||
'jpg', | ||
'jpeg', | ||
'gif', | ||
'svg', | ||
// fonts | ||
'woff', | ||
'woff2', | ||
'eot', | ||
'tff', | ||
'otf', | ||
] | ||
|
||
export const pwaPlugin: Plugin<PwaPluginOptions> = ({ | ||
serviceWorkerFilename = 'service-worker.js', | ||
...generateSWConfig | ||
}) => ({ | ||
name: '@vuepress/plugin-pwa', | ||
|
||
clientAppSetupFiles: path.resolve(__dirname, './clientAppSetup.js'), | ||
|
||
define: { | ||
__PWA_SW_FILENAME__: serviceWorkerFilename, | ||
}, | ||
|
||
async onGenerated(app) { | ||
await withSpinner('Generating service worker')(async () => { | ||
// lazy-load workbox-build | ||
const generateSW: typeof GenerateSWFunc = require('workbox-build/build/generate-sw') | ||
|
||
const globDirectory = app.dir.dest() | ||
const swDest = app.dir.dest(serviceWorkerFilename) | ||
|
||
const { warnings } = await generateSW({ | ||
dontCacheBustURLsMatching: new RegExp( | ||
`\\.[0-9a-f]{8}\\.(${assetsExtensions.join('|')})$` | ||
), | ||
globPatterns: [`**/*.{${assetsExtensions.join(',')}}`], | ||
mode: app.env.isDebug ? 'development' : 'production', | ||
sourcemap: app.env.isDebug, | ||
...generateSWConfig, | ||
// should not be override by user config | ||
globDirectory, | ||
swDest, | ||
}) | ||
|
||
warnings.forEach((warning) => | ||
logger.warn('[@vuepress/plugin-pwa]', warning) | ||
) | ||
}) | ||
}, | ||
}) | ||
|
||
export default pwaPlugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
{ | ||
"extends": "../../../tsconfig.base.json", | ||
"references": [ | ||
{ "path": "../client/tsconfig.build.json" }, | ||
{ "path": "../core/tsconfig.build.json" }, | ||
{ "path": "../utils/tsconfig.build.json" }, | ||
{ "path": "./tsconfig.esm.json" }, | ||
{ "path": "./tsconfig.cjs.json" } | ||
], | ||
"files": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"extends": "../../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"module": "CommonJS", | ||
"rootDir": "./src", | ||
"outDir": "./lib" | ||
}, | ||
"include": ["./src/index.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "../../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"module": "ES2020", | ||
"rootDir": "./src", | ||
"outDir": "./lib" | ||
}, | ||
"include": ["./src"], | ||
"exclude": ["./src/index.ts"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"extends": "../../../tsconfig.base.json", | ||
"include": ["./src", "./__tests__"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters