import { Plugin } from 'vite' import fs from 'fs' import path from 'path' interface FileWatcherOptions { // 目标可以是文件路径或文件夹路径 file: string; // 回调函数,接收变化的文件路径、内容(如果有)和变化类型 fn: (filePath: string, content?: string, eventType?: 'add' | 'change' | 'unlink') => void; // 防抖延迟,默认300ms delay?: number; } export function fileWatcher(options: FileWatcherOptions): Plugin { const {file, fn, delay = 300} = options const targetPath = path.resolve(file) let debounceTimer: NodeJS.Timeout | null = null // 检查目标是否为文件夹 const isDir = fs.existsSync(targetPath) && fs.statSync(targetPath).isDirectory() console.log('正在监听文件:' + targetPath) return { name: 'file-watcher-plugin', configureServer(server) { // 添加要监听的目标(文件或文件夹) server.watcher.add(targetPath) // 处理文件/文件夹变化的通用函数 const handleChange = (filePath: string, eventType: 'add' | 'change' | 'unlink') => { if (isDir && !filePath.startsWith(targetPath)) { return } if (!isDir && filePath !== targetPath) { return } // 防抖处理 if (debounceTimer) { clearTimeout(debounceTimer) } debounceTimer = setTimeout(async () => { try { let content: string | undefined if (!isDir) { content = fs.readFileSync(filePath, 'utf-8') } fn(filePath, content, eventType) } catch (error) { console.error('处理文件变化时出错:', error) } }, delay) } if (isDir) { // 监听文件新增 server.watcher.on('add', (filePath) => { handleChange(filePath, 'add') }) // 监听文件删除 server.watcher.on('unlink', (filePath) => { handleChange(filePath, 'unlink') }) } // 监听文件修改 server.watcher.on('change', (filePath) => { handleChange(filePath, 'change') }) }, } }