English | 简体中文
unplugin-update-notice
Monitor web page updates and notify users to reload the page
The git commit hash, package.json version, build timestamp, and custom version are used as the version number, and the version number is written to the json file at compile time. The client polls the server for the version number, or the browser window for visibilitychange, focus events, etc. If it is different, the user is notified to reload the page. If it is not the same, it notifies the user to reload the page.
When will updates be detected (fetch version.json)?
- first load page.
- poll (default: 10 * 60 * 1000 ms).
- script resource loading failure detected (404 ?).
- when the tab page is refocus or revisible.
Install
# npm
npm i unplugin-monitor-update -D
# pnpm
pnpm add unplugin-monitor-update -D
# yarn
yarn add unplugin-monitor-update -D
Vite
// vite.config.ts
import unpluginMonitorUpdate from 'unplugin-monitor-update/vite'
export default defineConfig({
plugins: [
unpluginMonitorUpdate({ /* options */ }),
],
})
Example: playground/
Rollup
// rollup.config.js
import unpluginMonitorUpdate from 'unplugin-monitor-update/rollup'
export default {
plugins: [
unpluginMonitorUpdate({ /* options */ }),
],
}
Webpack
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-monitor-update/webpack')({ /* options */ })
]
}
Nuxt
// nuxt.config.js
export default defineNuxtConfig({
modules: [
['unplugin-monitor-update/nuxt', { /* options */ }],
],
})
This module works for both Nuxt 2 and Nuxt Vite
Vue CLI
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-monitor-update/webpack')({ /* options */ }),
],
},
}
esbuild
// esbuild.config.js
import { build } from 'esbuild'
import unpluginMonitorUpdate from 'unplugin-monitor-update/esbuild'
build({
plugins: [unpluginMonitorUpdate()],
})
index.html
caching!
Important: Disable If index.html
is cached, the update notification may still appear after refreshing, so it is necessary to disable the caching of index.html
. This is also a best practice for deploy SPA applications.
To disable caching through nginx
:
# nginx.conf
location / {
index index.html index.htm;
if ( $uri = '/index.html' ) { # disabled index.html cache
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
try_files $uri $uri/ /index.html;
}
Directly disable caching through html meta
tags:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
</head>
</html>
Listening for notification events
// Listening for notification events
document.body.addEventListener('unplugin_monitor_update_event', (e) => {
const { version, options } = e.detail
// write some code, show your custom notification and etc.
console.log('System needs to be updated!')
})
Options
export interface Options {
/**
* The type of generated version
* * commit_hash: git commit hash
* * package: package.json version
* * timestamp: timestamp
* * custom: custom version
* */
versionType?: VersionType
/**
* custom version, if versionType is 'custom', this option is required
*/
customVersion?: string;
/**
* Monitoring modalities
* * polling: Polling monitoring
* * windowFocus: Monitor when window is focused
* * immediately: Monitoring immediately after page load
* * loadScriptError: Page script load failure(404)
* * windowVisibility: window visible
*/
monitorMode?: MonitorMode | MonitorMode[]
/**
* Monitoring intervals
* @default 10 * 60 * 1000
*/
checkInterval?: number
/**
* whether to output version in console
*
* you can also pass a function to handle the version
* ```ts
* logVersion: (version) => {
* console.log(`version: %c${version}`, 'color: #1890ff') // this is the default behavior
* }
* ```
* @default true
*/
logVersion?: boolean | ((version: string) => void)
/**
*
* Base public path for inject file, Valid values include:
* * Absolute URL pathname, e.g. /foo/
* * Full URL, e.g. https://foo.com/
* * Empty string(default) or ./
*
* !!! Don't forget / at the end of the path
*/
injectFileBase?: string
/**
* extra data in version.json
*
* @default {}
*/
extra?: Record<string, any>
}
export type VersionType = 'commit_hash' | 'package' | 'timestamp' | 'custom'
export type MonitorMode = 'polling' | 'windowFocus' | 'immediate' | 'loadScriptError' | 'windowVisibility'
Methods
name | params | describe |
---|---|---|
window.monitorSystemUpdate | manual check update, a function wrap by debounce(10 * 60 * 1000ms) |
interface Window {
/** version number */
__UNPLUGIN_MONITOR_UPDATE_VERSION__: string
/**
* don't call this function in manual。
*/
setupMonitorPlugin: (options: Options) => void
monitorSystemUpdate: () => void
}
interface GlobalEventHandlersEventMap {
unplugin_monitor_update_notice: CustomEvent<{ version: string; options: Options }>;
}