Skip to content

Commit

Permalink
feat: add possibility of debouncing the reload behaviour so that only…
Browse files Browse the repository at this point in the history
… ONE reload happens for a certain amount of time
  • Loading branch information
Bernat Jufré committed Jun 29, 2023
1 parent 86cb89e commit 0de6d18
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 20 deletions.
46 changes: 28 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -59,35 +57,47 @@ To see which file globbing options are available, check [picomatch].
The following options can be provided:

- <kbd>root</kbd>

Files will be resolved against this directory.

__Default:__ `process.cwd()`
**Default:** `process.cwd()`

``` js
```js
FullReload('config/routes.rb', { root: __dirname }),
```
```

- <kbd>delay</kbd>

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 });
```

- <kbd>debounce</kbd>

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
we only send one `full-reload` to Vite.

**Default:** `0`

```js
FullReload("app/views/**/*", { debounce: 100 });
```

- <kbd>always</kbd>

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

Expand Down
16 changes: 14 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -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'

/**
Expand All @@ -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
* we only send one `full-reload` to Vite.
*
* @default 0
*/
debounce?: number

/**
* Whether to log when a file change triggers a full reload.
* @default true
Expand Down Expand Up @@ -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 })
}
Expand Down

0 comments on commit 0de6d18

Please sign in to comment.