Writing
一组关于代码、工具与判断的长期笔记。它们从具体实践出发,保留问题形成的过程,也记录那些在速度之外仍值得反复辨认的细节。
-
浏览器翻译插件上线后,真正麻烦的是适配真实网页
浏览器翻译插件在测试页面里跑通并不难,麻烦的是它要长期面对 SPA 路由、动态加载、复杂布局、站点样式和局部失败。上线以后,我更多时间花在让它稳定适配真实网页,而不是继续堆翻译功能。
-
词典查不到的时候,AI 兜底也不能随便兜
Parallel Translate 里有些词不是普通单词,而是品牌、银行、产品名或缩写。直接让 LLM 接管所有未命中查词会变慢也会变脏,我最后把它限制成只在用户主动查词、有上下文时触发的语境化兜底。
-
查词接口不能为了完整,把用户卡在原地
在 Parallel Translate 里,主动查词最重要的是先让用户看到可用结果。后来我把查词接口从同步等待外部富化,改成先返回词库结果,再把音频、例句和补充释义放到后台慢慢补齐。
-
划词翻译面板为什么难做
划词翻译看起来只是选中文字后弹出一个小面板,真正难的是选区解释、浮层定位、样式隔离、词典与 AI 编排、发音播放和生词状态同步。一个小面板背后,其实是一套横跨页面、扩展和后台服务的交互系统。
-
给 Next.js 套一层 Electron 壳:零改动打包成桌面应用
StockTracker 之前是一个纯 Web 服务,想着 Electron 易于分发,尝试把它打包成桌面客户端。本文记录整个过程中 Next.js 代码零改动的架构设计、踩过的坑和最终方案。
-
我如何组织 AI 翻译扩展的缓存、批处理与 Provider
在双语阅读扩展里,翻译请求如果由页面脚本随手发送,很快会变慢、变贵、难以恢复。我在 Parallel Translate 中如何把缓存、批处理、多 Provider 与页面渲染拆开处理。
-
我如何在浏览器扩展中把网页变成双语阅读视图
我最近在做一个双语阅读浏览器扩展。真正棘手的并不是把一句英文交给翻译服务,而是在不破坏原网页的前提下,找到正文、按需翻译、保留交互,并且随时还原页面。
-
为什么我用 SQLite 作为个人投资系统的数据底座
在 StockTracker 里,我没有把 SQLite 当成一个简陋的本地缓存,而是把它作为个人投资账本和 AI 工作流状态的本地数据底座。这篇文章从持久化方案对比讲到 SQLite 的机制和取舍。
-
为什么投资系统不能只使用 JavaScript number 计算金额
JavaScript 的 number 很方便,但它表达的是二进制浮点数,不是金融系统需要的十进制语义。这篇文章从 0.1 + 0.2 讲到手续费、每股成本、FIFO 成本队列和 big.js 选型。
-
AI 对话里的逐字输出,背后其实是一条不断吐数据的 HTTP 响应
很多 AI 对话产品看起来像是在一个字一个字地打出来,背后通常不是 WebSocket,而是基于 text/event-stream 或 ReadableStream 的 HTTP 流式响应。这篇文章拆解 SSE、Content-Type 和前端增量渲染的实现细节。