diff --git a/README.md b/README.md
index ea28f01..56cba5f 100644
--- a/README.md
+++ b/README.md
@@ -40,14 +40,12 @@ npm i -D vite-plugin-full-reload # yarn add -D vite-plugin-full-reload
Add it to your plugins in `vite.config.ts`
```ts
-import { defineConfig } from 'vite'
-import FullReload from 'vite-plugin-full-reload'
+import { defineConfig } from "vite";
+import FullReload from "vite-plugin-full-reload";
export default defineConfig({
- plugins: [
- FullReload(['config/routes.rb', 'app/views/**/*'])
- ],
-})
+ plugins: [FullReload(["config/routes.rb", "app/views/**/*"])],
+});
```
This is useful to trigger a page refresh for files that are not being imported, such as server-rendered templates.
@@ -59,35 +57,47 @@ To see which file globbing options are available, check [picomatch].
The following options can be provided:
- root
-
+
Files will be resolved against this directory.
- __Default:__ `process.cwd()`
+ **Default:** `process.cwd()`
- ``` js
+ ```js
FullReload('config/routes.rb', { root: __dirname }),
- ```
+ ```
- delay
How many milliseconds to wait before reloading the page after a file change.
It can be used to offset slow template compilation in Rails.
- __Default:__ `0`
-
+ **Default:** `0`
+
```js
- FullReload('app/views/**/*', { delay: 100 })
- ```
+ FullReload("app/views/**/*", { delay: 100 });
+ ```
+
+- debounce
+
+ How many milliseconds to postpone the execution of the reload function since it's last invocation.
+ This is useful if you have a lot of changes in a short period of time and need to make sure that
+ only one `full-reload` event is sent to Vite.
+
+ **Default:** `0`
+
+ ```js
+ FullReload("app/views/**/*", { debounce: 100 });
+ ```
- always
Whether to refresh the page even if the modified HTML file is not currently being displayed.
- __Default:__ `true`
-
+ **Default:** `true`
+
```js
- FullReload('app/views/**/*', { always: false })
- ```
+ FullReload("app/views/**/*", { always: false });
+ ```
## Acknowledgements
diff --git a/src/index.ts b/src/index.ts
index 7fafa22..1f74479 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,6 +1,7 @@
import { relative, resolve } from 'path'
import colors from 'picocolors'
import picomatch from 'picomatch'
+import debounce from 'debounce'
import { type PluginOption, type ViteDevServer, normalizePath } from 'vite'
/**
@@ -19,6 +20,15 @@ export interface Config {
*/
delay?: number
+ /**
+ * How many milliseconds to postpone the execution of the reload function since it's last invocation.
+ * This is useful if you have a lot of changes in a short period of time and need to make sure that
+ * only only one `full-reload` event is sent to Vite.
+ *
+ * @default 0
+ */
+ debounce?: number
+
/**
* Whether to log when a file change triggers a full reload.
* @default true
@@ -48,13 +58,15 @@ export default (paths: string | string[], config: Config = {}): PluginOption =>
config: () => ({ server: { watch: { disableGlobbing: false } } }),
configureServer ({ watcher, ws, config: { logger } }: ViteDevServer) {
- const { root = process.cwd(), log = true, always = true, delay = 0 } = config
+ const { root = process.cwd(), log = true, always = true, delay = 0, debounce: debounceMs = 0 } = config
const files = normalizePaths(root, paths)
const shouldReload = picomatch(files)
+ const sendReloadEvent = (path: string) => setTimeout(() => ws.send({ type: 'full-reload', path: always ? '*' : path }), delay)
+ const reload = debounceMs ? debounce(sendReloadEvent, debounceMs) : sendReloadEvent
const checkReload = (path: string) => {
if (shouldReload(path)) {
- setTimeout(() => ws.send({ type: 'full-reload', path: always ? '*' : path }), delay)
+ reload(path)
if (log)
logger.info(`${colors.green('page reload')} ${colors.dim(relative(root, path))}`, { clear: true, timestamp: true })
}