Skip to content

Commit

Permalink
feat: add pattern and throttle options
Browse files Browse the repository at this point in the history
  • Loading branch information
innocenzi committed Feb 2, 2023
1 parent 40b55d0 commit ecead8a
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 16 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ Optionally, you can directly pass a runner or a list of runner to the plugin opt
| `startup` | `bool` | Whether the command should run when Vite starts | `true` |
| `name` | `string` | An identifier for the runner, used in logs | |
| `condition` | `() => boolean` | A function that should return true for a file change to execute the runner | |
| `pattern` | `string` or `string[]` | A minimatch pattern which files must match | |
| `run` | `() => string[]` or `string[]` | A command executed when a file changed and the condition matches | |
| `onFileChanged` | `() =>void` | A callback executed when a file changed and the condition matches | |
| `delay` | `number` | Delay before the command is executed | `50` |
| `throttle` | `number` | Delay before the command can be re-executed | `50` |

<p align="center">
<br />
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"dependencies": {
"@antfu/utils": "^0.5.2",
"debug": "^4.3.4",
"minimatch": "^6.1.6",
"picocolors": "^1.0.0"
}
}
16 changes: 15 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 30 additions & 14 deletions src/run.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { spawn } from 'node:child_process'
import path from 'node:path'
import { loadEnv, Plugin } from 'vite'
import makeDebugger from 'debug'
import c from 'picocolors'
import { toArray } from '@antfu/utils'
import { minimatch } from 'minimatch'
import type { Options, ResolvedRunOptions, Runner, RunnerHandlerParameters } from './types'

const PLUGIN_NAME = 'vite:plugin:run'
const debug = makeDebugger(PLUGIN_NAME)
const throttles: Set<string> = new Set()

function warn(prefix: string, message: string) {
process.stdout.write(c.bold(`${c.yellow(`(!) ${prefix}`)} ${message}\n`))
}

// function log(prefix: string, message: string) {
// process.stdout.write(c.bold(`${c.cyan(`${prefix}`)} ${message}\n`))
// }

/**
* Reload when some files are changed.
*/
Expand Down Expand Up @@ -51,16 +50,12 @@ export function run(options: Options = []): Plugin {
}
})
},
configureServer(server) {
server.watcher
.on('add', (path) => handleReload(resolvedOptions, { file: path, server, type: 'add' }))
.on('change', (path) => handleReload(resolvedOptions, { file: path, server, type: 'change' }))
.on('unlink', (path) => handleReload(resolvedOptions, { file: path, server, type: 'unlink' }))
},
handleHotUpdate({ file }) {
handleHotUpdate({ file, server }) {
if (resolvedOptions.skipDts && file.endsWith('.d.ts')) {
return []
}

handleReload(resolvedOptions, { file, server })
},
}
}
Expand All @@ -73,12 +68,23 @@ function handleReload(options: ResolvedRunOptions, parameters: RunnerHandlerPara
return
}

debug(`${c.gray(file)} changed, applying its handler...`)
const patterns = !Array.isArray(runner.pattern)
? [runner.pattern!].filter(Boolean)
: runner.pattern

for (const pattern of patterns) {
if (!minimatch(file, path.resolve(parameters.server.config.root, pattern))) {
return
}
}

handleRunner(runner, options, parameters)
})
}

function handleRunner(runner: Runner, options: ResolvedRunOptions, parameters: RunnerHandlerParameters) {
debug(`${c.gray(parameters.file)} changed, applying its handler...`)

try {
if (typeof runner.onFileChanged === 'function') {
runner.onFileChanged?.(parameters)
Expand All @@ -99,9 +105,19 @@ function handleRunnerCommand(options: ResolvedRunOptions, runner: Runner) {
}

const name = getRunnerName(runner)
debug(`Running ${name}...`)

// Run after a delay
// Check throttles
if (throttles.has(name)) {
debug(`${name} is throttled.`)
return
}

// Throttles the runner
throttles.add(name)
setTimeout(() => throttles.delete(name), runner.throttle ?? 500)

// Runs the runner after the configured delay
debug(`Running ${name}...`)
setTimeout(() => {
const child = spawn(
getExecutable(options, getRunnerCommand(runner)),
Expand Down
12 changes: 11 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export type RunnerHandler = (parameters: RunnerHandlerParameters) => void
export interface RunnerHandlerParameters {
file: string
server: ViteDevServer
type: 'add' | 'change' | 'unlink'
}

export interface Runner {
Expand All @@ -49,6 +48,11 @@ export interface Runner {
*/
condition?: (file: string) => boolean

/**
* File changes must correspond to the given minimatch pattern.
*/
pattern?: string | string[]

/**
* Executed when a watched file meets the condition.
*/
Expand All @@ -64,4 +68,10 @@ export interface Runner {
* @default 50 ms
*/
delay?: number

/**
* Delay before the handler can be executed again (in ms)
* @default 500 ms
*/
throttle?: number
}

0 comments on commit ecead8a

Please sign in to comment.