如何基于parcelwatcher打造文件双版本备份的工具?

摘要:背景 在日常使用AI进行开发和工作中,经常遇到以下场景: AI修改代码后发现改错了,想回退到之前的版本 AI上下文溢出导致文件被删除或内容被清空 重要文档被AI误删或误改,找不到历史版本 虽然 Git 可以解决代码版本问题,但是实际工作中是
背景 在日常使用AI进行开发和工作中,经常遇到以下场景: AI修改代码后发现改错了,想回退到之前的版本 AI上下文溢出导致文件被删除或内容被清空 重要文档被AI误删或误改,找不到历史版本 虽然 Git 可以解决代码版本问题,但是实际工作中是不可能将每次修改都commit,不仅费时费力而且不规范,此时需要一个更轻量的解决方案。 FileBackupGuardian 就是为解决这些问题而设计的桌面应用,它可以: 实时监听指定目录的文件变更 自动创建备份,保留修改前后两个版本 提供差异对比功能,直观查看修改内容 支持一键恢复到任意历史版本 技术选型 类别 技术 选择理由 桌面框架 Electron 29 跨平台支持,生态成熟 前端框架 Vue 3 + TypeScript 组合式 API,类型安全 状态管理 Pinia 轻量,与 Vue 3 深度集成 构建工具 Vite 5 开发体验好,构建速度快 文件监听 @parcel/watcher 性能优异,原生支持递归监听 差异计算 diff-match-patch Google 开源,算法成熟 核心功能实现 1. 实时文件监听 文件监听是整个应用的核心。使用 @parcel/watcher 替代 Node.js 原生的 fs.watch,因为它: 基于 native 实现,性能更好 支持递归监听,无需手动遍历子目录 事件去重机制,避免重复触发 // watcher-manager.ts import * as parcelWatcher from '@parcel/watcher'; async startWatching(watchPath: WatchPath): Promise<void> { const subscription = await parcelWatcher.subscribe( watchRoot, async (error, events) => { if (error) { this.updateStatus(watchPath.id, { error: error.message }); return; } await this.handleParcelEvents(watchPath, events); } ); this.watchers.set(watchPath.id, subscription); } 2. 双版本备份机制 这是本工具的特色功能。当文件被修改时,我们需要: 变更前备份:在文件写入前,保存原始内容 变更后备份:文件写入完成后,保存新版本 这样用户可以对比任意修改前后差异,而不仅仅是对比当前版本和备份版本。 实现的关键是利用文件内容缓存: // 使用 LRU 缓存存储文件内容(100MB) private fileContentCache = new LRUCache<string, CacheEntry>(100 * 1024 * 1024); // 文件变更前,从缓存获取原始内容 private async handleFileChange(filePath, watchPathId, eventType) { if (eventType === 'change') { const cachedContent = this.fileContentCache.get(filePath); if (cachedContent) { // 使用缓存内容创建"变更前备份" await this.backupManager.createBackupWithContent(filePath, cachedContent); } } // 文件变更后,创建"变更后备份" await this.backupManager.createPostChangeBackup(filePath, preBackupId); } 3. Worker 线程优化 大文件的差异计算和文件计数是耗时操作,如果在主线程执行会阻塞 UI。
阅读全文