Skip to content

Instantly share code, notes, and snippets.

@bnhansn
Created January 2, 2024 18:16
Show Gist options
  • Save bnhansn/eb5ab689d79e76457356a83b7544f5fd to your computer and use it in GitHub Desktop.
Save bnhansn/eb5ab689d79e76457356a83b7544f5fd to your computer and use it in GitHub Desktop.
Vite Plugin Touch File
import fs from 'fs'
import path from 'node:path'
import process from 'node:process'
import micromatch from 'micromatch'
import type { Plugin } from 'vite'
export interface VitePluginTouchFileOptions {
touchFile: string
watchFiles: string | string[]
glob?: boolean
delay?: number
}
let i = 0
function toArray<T>(arr: T | T[] | undefined): T[] {
if (!arr) {
return []
}
if (Array.isArray(arr)) {
return arr
}
return [arr]
}
export default function VitePluginTouchFile(
options: VitePluginTouchFileOptions
): Plugin {
const { delay = 0, glob: enableGlob = true, touchFile, watchFiles } = options
let root = process.cwd()
let watchGlobs: string[] = []
let timer: ReturnType<typeof setTimeout> | undefined
function clearTimer() {
clearTimeout(timer)
}
function scheduleTouch() {
clearTimer()
timer = setTimeout(() => {
fs.readFile(touchFile, (err, data) => {
if (err) {
throw err
}
fs.writeFile(touchFile, data, (err) => {
if (err) {
throw err
}
})
})
}, delay)
}
return {
name: `vite-plugin-touch-file:${i++}`,
apply: 'serve',
config(c) {
if (!enableGlob) {
return
}
if (!c.server) {
c.server = {}
}
if (!c.server.watch) {
c.server.watch = {}
}
c.server.watch.disableGlobbing = false
},
configResolved(config) {
root = config.root
watchGlobs = toArray(watchFiles).map((i) => path.posix.join(root, i))
},
configureServer(server) {
server.watcher.add(watchGlobs)
server.watcher.on('add', handleFileChange)
server.watcher.on('change', handleFileChange)
server.watcher.on('unlink', handleFileChange)
function handleFileChange(file: string) {
if (micromatch.isMatch(file, watchGlobs)) {
scheduleTouch()
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment