mirror of
https://github.com/linshenkx/prompt-optimizer.git
synced 2026-05-07 05:56:49 +08:00
- 导出偏好设置服务类型和实现,增强服务可用性。 - 实现`ElectronPreferenceServiceProxy`和`PreferenceService`,提供偏好设置管理功能。 - 更新组件,使用偏好设置服务替代原有存储逻辑,提升代码可维护性和一致性。 - 集成偏好设置服务的IPC处理逻辑,确保主进程正确处理相关请求。 - 新增重构UI层状态持久化架构任务,目标是将UI层对`useStorage`的直接依赖替换为`PreferenceService`。 - 优化IPC通信,新增对流式处理的支持,增强Prompt服务功能。 - 集成Prompt服务的IPC处理逻辑,并新增成功和错误响应辅助函数,简化IPC处理逻辑,提升代码可读性和一致性;同时优化多个IPC处理函数,确保在发生错误时能够统一返回错误信息,增强错误管理。 - 新增对`iteratePrompt`、`testPrompt`、`getHistory`、`getIterationChain`等方法的支持,暴露Prompt服务接口,方便前端调用,扩展前端与主进程的交互能力。 - 删除不再使用的Markdown输出规则和AI开发工作流程文档,提升项目的可维护性和文档的清晰度。
7.8 KiB
7.8 KiB
开发经验记录
记录开发过程中的重要经验和最佳实践。
🔧 构建与依赖管理 (Monorepo & Vite)
经验: 在 pnpm workspace (monorepo) 中,当一个包(如@core)需要同时服务于前端(Vite构建的@ui包)和后端(Node.js/Electron)时,处理导出和依赖关系需要特别小心,以避免构建冲突。
场景:
- 一个
@core包,其中一部分代码(如tRPC路由)仅用于后端,另一部分是通用代码。 - 一个
@ui包(使用Vite构建),依赖@core包。 - 一个
@desktop包(使用Electron),也依赖@core包,并需要使用其仅后端的代码。
问题:
- 如果
@core包在其主入口 (index.ts) 导出了仅后端的代码,会导致前端应用打包进不必要的服务器依赖(如@trpc/server)。 - 如果为了解决问题1,使用
package.json的exports映射为后端代码创建单独入口,可能会破坏Vite的依赖解析机制,导致@ui包构建失败。 - 如果在
@ui的Vite配置中将@core包设为external,会增加最终应用的配置复杂性,使其无法"开箱即用"。
最佳实践 / 解决方案:
- 组件库自包含 (Batteries Included): 在
@ui包的vite.config.ts中,移除内部依赖(如@core)的external配置。让UI库成为一个完整的、内置所有必要依赖的自包含产品。 - 核心包多入口构建: 在
@core包中,使用tsup等工具配置多入口点构建。一个入口是提供给前端和大部分后端的公共API (index.ts),另一个是仅用于特定后端的专门文件(如router.ts)。 - 分离导出与实现 (公共API vs 内部路径):
- 不要在
package.json中为仅后端的代码创建复杂的exports映射。保持主exports干净、简单,只指向公共API。 - 在需要使用仅后端代码的地方(如
desktop/main.js),直接通过相对文件路径从dist目录中require编译后的文件。
- 不要在
代码示例:
packages/core/package.json(scripts):"build": "tsup src/index.ts src/services/trpc/router.ts --format cjs,esm --dts"packages/desktop/main.js(import):const { createAppRouter } = require('@prompt-optimizer/core/dist/services/trpc/router.cjs');
结论: 这种"公共API + 内部路径"的策略,优雅地解决了前后端对同一个包的不同需求,保证了Vite构建的顺利进行,也维持了后端功能的可用性。
核心原则: 必须同时满足现代前端构建工具(如Vite)和后端环境(Node.js)的模块解析规则。核心是遵守Node.js的exports封装性,并以此为基础解决Vite的兼容问题。
遇到的问题演进:
- 前端加载后端代码:
@core包的index.ts导出了仅服务器端的代码,导致浏览器报错。 - Vite构建失败: 为解决问题1,尝试使用
exports为后端代码创建单独入口,但这种多入口配置导致Vite无法解析依赖。 - Node.js路径未导出 (ERR_PACKAGE_PATH_NOT_EXPORTED): 为解决问题2,尝试让后端直接引用内部文件路径,但这违反了Node.js的模块封装规则,因为
exports字段存在时,所有访问必须经过它的允许。
最终的最佳实践 (The Standard Way):
- 组件库自包含 (Batteries Included):
- 在
@ui包的vite.config.ts中,移除内部依赖(如@core)的external配置。让UI库成为一个完整的、内置所有必要依赖的自包含产品。这是解决问题的起点。
- 在
- 在核心包中明确声明所有导出:
- 在
@core包的package.json中,使用exports字段明确声明所有需要被外部访问的路径,无论是给前端还是后端使用。 - 使用
tsup等工具进行多入口点构建,确保exports中声明的每个路径都有对应的编译产物。
- 在
- 所有消费者都使用标准路径:
- 无论是前端还是后端,都应该通过
exports中声明的标准路径来导入模块 (e.g.,'@prompt-optimizer/core'或'@prompt-optimizer/core/trpc-router')。 - 禁止任何包从另一个包的内部文件路径(如
dist/...)进行导入。
- 无论是前端还是后端,都应该通过
代码示例 (最终正确配置):
packages/core/package.json:"exports": { ".": { "import": "./dist/index.js", "require": "./dist/index.cjs" }, "./trpc-router": { "import": "./dist/services/trpc/router.js", "require": "./dist/services/trpc/router.cjs" } }, "scripts": { "build": "tsup src/index.ts src/services/trpc/router.ts --format cjs,esm --dts" }packages/desktop/main.js:const { createAppRouter } = require('@prompt-optimizer/core/trpc-router');
结论: 这个标准化的解决方案保证了 @core 包的强封装性,同时为不同环境的消费者提供了清晰、稳定、唯一的访问接口。如果在此基础上Vite仍然构建失败,那么下一步应该去调整Vite自身的配置(如 resolve.alias 或 optimizeDeps.exclude),而不是破坏包的封装规则。
🔧 技术经验
架构设计
- [经验描述] - [适用场景] - [记录日期]
错误处理
- [错误类型] - [解决方案] - [预防措施] - [记录日期]
性能优化
- [优化点] - [优化方法] - [效果] - [记录日期]
测试实践
- [测试类型] - [最佳实践] - [工具推荐] - [记录日期]
🛠️ 工具配置
开发工具
- [工具名称] - [配置要点] - [使用技巧] - [记录日期]
调试技巧
- [问题类型] - [调试方法] - [工具使用] - [记录日期]
📚 学习资源
有用文档
- [文档标题] - [链接] - [要点总结] - [记录日期]
代码示例
- [功能描述] - [代码片段或文件位置] - [使用场景] - [记录日期]
🚫 避坑指南
常见错误
- [错误描述] - [原因分析] - [避免方法] - [记录日期]
设计陷阱
- [设计问题] - [问题后果] - [正确做法] - [记录日期]
🔄 流程改进
工作流优化
- 经验: 在Monorepo中设计开发命令时,要避免并行进程操作同一目录导致的"赛跑条件"。
- 场景: 使用
concurrently并行执行多个任务,其中一个任务是Vite开发服务器(vite dev),另一个是其依赖库的监视构建任务(vite build --watch)。 - 问题:
vite dev在启动时需要读取依赖库(如@ui)的构建产物(如dist/style.css),而vite build --watch在同一时间可能正在清理或重写该dist目录,导致文件读取失败,引发样式丢失等问题。 - 最佳实践:
- 信任Vite开发服务器:在开发环境下,应该最大限度地利用Vite开发服务器的内置能力。它能够直接处理对工作区内其他包(workspace-local packages)的依赖,并从它们的源文件(
src)进行实时编译和热更新。 - 避免预构建和监视:因此,在启动主应用的开发服务器时,不应该同时运行其依赖库的
build --watch任务。 - 简化并行命令: 开发命令应只包含主应用的开发服务器(如
vite dev)和其他必要的后端服务(如electron .)。让单个Vite实例全权负责所有前端代码的编译。
- 信任Vite开发服务器:在开发环境下,应该最大限度地利用Vite开发服务器的内置能力。它能够直接处理对工作区内其他包(workspace-local packages)的依赖,并从它们的源文件(
- 示例 (package.json):
- 错误示范:
concurrently "pnpm -F @ui watch" "pnpm -F @web dev" - 正确示范:
concurrently "pnpm -F @web dev" "pnpm -F @desktop dev"(假设web负责所有UI,desktop是后端)
- 错误示范:
- 记录日期: 2024-07-28
文档管理
- [管理经验] - [工具使用] - [效率提升] - [记录日期]
📝 使用说明
- 及时记录 - 遇到重要经验立即记录
- 分类整理 - 按照上述分类组织内容
- 定期回顾 - 每周回顾一次,提取可复用经验
- 归档整理 - 任务完成时将相关经验归档到archives