TRAE SOLO实战成功展示&总结:一个所见即所得的笔记软体

写在前面

先说结论:我是个前端半吊子,但我用 AI 写了一个功能完整的桌面笔记应用。

FireFire,Electron + React 技术栈,支持三大平台,123 个源文件,2 万多行代码。从 2022 年 8 月第一次 commit 到现在 v0.6.29,该有的功能基本都有了------富文本编辑、知识图谱、WebDAV 同步、AI 对话、版本历史......

如果你问我:这些代码你都看得懂吗?

emmm......大部分吧(心虚)。

上篇文章:TRAE SOLO实战:一个所见即所得的笔记软体

真香警告

说实话,一开始我对 AI 写代码这事儿是拒绝的。

改变我想法的是一个 B站视频嵌入功能。我当时的状态是:知道 Tiptap 是个编辑器框架,但它底层的 ProseMirror 是啥玩意儿?Node Extension 怎么写?完全不懂,文档看得我头大。

于是我抱着试试看的心态问了 TRAE,结果它直接给我整了这么一段:

javascript 复制代码
// src/common/extensions/biliBiliNode.js
const BiliBiliNode = Node.create({
    name: 'BiliBili',
    draggable: true,  // 还贴心地加上了拖拽功能

    addPasteRules() {
        return [
            nodePasteRule({
                // 这正则写得比我自己写的都优雅
                find: /^(https?:\/\/)?(www\.|player\.)?(bilibili\.com\/video\/)(BV[0-9a-zA-Z]*)[?/](.+)?$/g,
                type: this.type,
                getAttributes: match => {
                    return {src: match[4]}  // 精准提取 BV 号
                },
            }),
        ]
    },

    renderHTML({HTMLAttributes}) {
        const vid = HTMLAttributes.src;
        HTMLAttributes.src = `//player.bilibili.com/player.html?bvid=${vid}&page=1`
        return [
            'div',
            { 'data-bilibili-video': vid },
            ['iframe', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)],
        ];
    },
});

我当时的表情:😮

这代码不仅能跑,而且考虑到了各种 B站链接格式,还自动把链接转成嵌入式播放器。我自己写的话,光那个正则表达式就得调半天。

从那以后,真香。

我是怎么和 AI 搭伙干活的

混了一年之后,我总结出了一套"人机协作"的野路子:

1. 大事找 AI 商量,小事自己瞎搞

架构层面的决策,我会先让 AI 给我分析利弊。比如全文搜索这个功能,我最开始想的是:不就是遍历文件然后 indexOf 嘛,多大点事儿。

AI 说:兄弟,你这样一百个文件还行,一千个文件你等着卡死吧。

然后它给我科普了 SQLite FTS5(全文搜索引擎),还顺手写了这么一套:

javascript 复制代码
// electron/dbManager.js
createTables() {
    // 使用 WAL 模式,AI 说这样性能好(我也不知道为啥,但它说得对)
    this.db.pragma('journal_mode = WAL');

    // 创建全文搜索虚拟表
    this.db.exec(`
      CREATE VIRTUAL TABLE IF NOT EXISTS notes_fts USING fts5(
        title,
        content_text,
        content='notes',
        content_rowid='rowid'
      )
    `);

    // 触发器:笔记更新时自动更新索引
    // 这个我自己肯定想不到,手动维护索引迟早出 bug
    this.db.exec(`
      CREATE TRIGGER IF NOT EXISTS notes_ai AFTER INSERT ON notes BEGIN
        INSERT INTO notes_fts(rowid, title, content_text)
        VALUES (new.rowid, new.title, new.content_text);
      END;
    `);
}

事实证明这决策太对了。现在几百篇笔记搜索,毫秒级响应,丝滑。

2. 复杂功能拆着来,别想一口吃成胖子

[[双向链接]] 是我做过最复杂的功能之一。一开始我跟 AI 说"我要做个双向链接",它给我生成了一大坨代码,我直接懵了。

后来学聪明了,拆成小任务:

  • 第一步:识别 [[]] 语法
  • 第二步:把它变成可点击的链接
  • 第三步:点击后跳转
  • 第四步:输入时自动补全
  • 第五步:不存在的链接显示红色

一步一步来,每步都能测,出了 bug 也知道是哪儿的问题。

javascript 复制代码
// src/common/extensions/internalLinkExtension.js
addKeyboardShortcuts() {
    return {
      // 用户输入第二个 ] 时触发
      ']': ({ editor }) => {
        const textBefore = /* 获取光标前的文本 */;

        // 正则匹配 [[链接名
        const match = textBefore.match(/\[\[([^\]]+)$/);

        if (match) {
          // 把文本替换成链接节点
          editor.chain()
            .deleteRange({ from: start, to: end })
            .insertContent({
              type: this.name,
              attrs: { target: match[1], exists: false },
            })
            .run();

          // 顺便检查一下这个链接指向的笔记存不存在
          this.checkLinkExists(editor, match[1]);
          return true;
        }
        return false;
      },
    };
}

这种"化整为零"的方式,让我这个半吊子也能驾驭复杂功能。

3. 知识图谱:装X利器

说实话,做知识图谱纯粹是因为看 Obsidian 的图谱太酷了,我也想要。

D3.js 力导向图?听都没听过。但 AI 懂啊:

javascript 复制代码
// src/pages/graph/GraphView.jsx
const GraphView = () => {
    // 标签不同颜色,看着就专业
    const TAG_COLORS = [
        '#0f7b6c', '#2563eb', '#dc2626', '#9333ea',
        '#ea580c', '#0891b2', '#65a30d', '#db2777',
    ];

    // 点击标签筛选,还要保留关联节点(这个逻辑我想了半天,AI 秒出)
    const filteredData = React.useMemo(() => {
        if (selectedTag) {
            const filteredNodeIds = new Set(
                nodes.filter(n => n.tags?.includes(selectedTag)).map(n => n.id)
            );
            // 关联节点也要显示,不然图就断了
            links.forEach(link => {
                if (filteredNodeIds.has(link.source)) {
                    filteredNodeIds.add(link.target);
                }
            });
            // ...过滤逻辑
        }
        return { nodes, links };
    }, [graphData, selectedTag]);

    return <ForceGraph2D graphData={filteredData} /* 各种配置 */ />;
};

3. 对TRAE问自己项目与其它Obsidian的区别,还需要什么功能点

markdown 复制代码
## 缺失功能判断

-   最亟需补齐的功能是"本地安全与隐私保护":缺少应用级锁定、本地数据/设置加密,以及对敏感凭证(AI API Key、代理密码、WebDAV 账号)的安全存储。
-   当前敏感信息以明文保存在设置文件,且存在 `webSecurity: false` 的使用场景;这对用户数据安全与合规存在风险。

## 功能目标

-   引入"Vault 安全模式":在桌面端提供应用锁定、凭证安全存储、关键设置加密与自动锁定机制。
-   跨平台安全存储:macOS 使用 Keychain、Windows 使用 DPAPI、Linux 使用 libsecret;统一封装为主进程安全服务。
-   保障体验:默认不影响现有工作流;用户可一键启用,支持自动锁定与解锁流程。

## 技术实现

-   依赖与方案:

    -   使用 `keytar` 封装系统级安全存储,保存 API Key、代理密码、WebDAV 凭证。
    -   使用 `crypto` 的 AES-GCM(或 `libsodium-wrappers`)对本地 `setting.json` 中的敏感字段进行字段级加密;密钥以系统安全存储保护。
    -   初期不改动 `better-sqlite3` 数据库文件结构;后续独立评估 SQLCipher 全库加密与 FTS5 兼容性。

-   主进程服务:

    -   新增 `secureStore` 模块(getSecret/setSecret/deleteSecret),统一多平台实现与错误处理。
    -   新增 `vaultManager`(enable/disable/lock/unlock/isLocked),管理主密码(可选)、自动锁定计时、进程状态。
    -   IPC:暴露 `vault:*` 与 `secureStore:*` 接口至预加载;所有调用均白名单校验与输入校验。

-   预加载层:

    -   `contextBridge.exposeInMainWorld` 增加 `vault` 与 `secureStore` API;保持最小授权面。

-   渲染端 UI:

    -   设置页新增"安全"分区:启用 Vault、设置主密码(可选)、自动锁定时长、清除凭证。
    -   头部新增"锁定应用"入口与状态指示;锁定态显示解锁面板(主密码或系统生物识别)。

-   数据迁移:

    -   首次启用 Vault 时,将 `setting.json` 中的敏感字段迁移到 `secureStore`,并以加密占位符写回;生成一次性备份并提示用户校验。

## 流程与状态

-   首次启用:用户选择启用 → 可设置主密码 → 生成并存储加密密钥 → 迁移敏感数据。
-   应用启动:检测 Vault 状态;如启用则进入锁定态,解锁后加载设置与服务。
-   自动锁定:触发条件包括闲置超时、系统睡眠/唤醒、窗口最小化;解锁后恢复会话。

## 测试与验证

-   单元测试:`secureStore` 的多平台行为(通过 mock)、加解密正确性与错误路径覆盖。
-   集成测试:临时工作空间与设置文件迁移流程的回滚与容错验证。
-   安全检查:确保不在日志中输出密钥/敏感数据,渗透测试 checklist(路径校验、IPC 输入校验、预加载最小化)。

## 文档与配置

-   README 与设置说明:新增"安全与隐私"章节、启用步骤与注意事项;统一技术版本与许可证声明。
-   开发文档:主进程模块接口、预加载白名单、错误码约定。

## 后续扩展

-   评估数据库全库加密(SQLCipher)与 FTS5 的兼容与替代方案。
-   WebDAV 端到端加密通道(本地加密后再同步),以及冲突解决策略。
-   生物识别集成(macOS Touch ID、Windows Hello)与解锁体验增强。

翻车现场

当然也不是一路顺风,翻车的时候也不少。

翻车一:AI 的记性不如鱼

跨几次对话之后,AI 就开始"失忆"了。之前说好的变量命名规范?忘了。文件组织结构?什么结构?

后来我学乖了,专门写了个 README.md 文件,把项目架构、代码规范、重要决策全记下来,每次对话先让 AI 读一遍。相当于给它发了个"员工手册"。

翻车二:在 Mac 上跑得好好的......

Windows 用户:你的路径分隔符有问题。

我:???

AI 写的 path.join() 没问题,但有几个地方手动拼的 / 就出事了。现在我每次都会问一句:"这个在 Windows 上能跑吗?"

一点感悟

折腾了一年,最大的感悟就是:

AI 是外挂,不是代打。

它能让你 10 倍速写代码,但不能替你想清楚"要写什么"。架构设计、用户体验、产品方向------这些还得自己来。AI 只是把"实现"这个环节大大加速了。

另外就是学习方式变了。以前是先花两周看文档,再花两周写 demo,最后才敢动手做项目。现在是反过来------先干,不懂就问,边做边学。我对 Electron、Tiptap、SQLite 的理解,比任何时候都深,因为每个知识点都对应着一个实际问题。

最后说一句:有人觉得 AI 写代码是"作弊",我不这么看。

工具嘛,用就完了,现在自己用,有啥功能让TRAE给我写,也不用担心无人维护,哈哈哈哈。


对 FireFire 感兴趣可以去 GitHub 看看。更新日志:

相关推荐
Cassie燁1 小时前
el-button源码解读1——为什么组件最外层套的是Vue内置组件Component
前端·vue.js
vx_bscxy3221 小时前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
北极糊的狐1 小时前
Vue3 子组件修改父组件传递的对象并同步的方法汇总
前端·javascript·vue.js
spionbo1 小时前
Vue3 前端分页功能实现的技术方案及应用实例解析
前端
Zyx20071 小时前
JavaScript 作用域与闭包(下):闭包如何让变量“长生不老”
javascript
AI绘画小331 小时前
Web 安全核心真相:别太相信任何人!40 个漏洞挖掘实战清单,直接套用!
前端·数据库·测试工具·安全·web安全·网络安全·黑客
7***n752 小时前
前端设计模式详解
前端·设计模式·状态模式
u***j3242 小时前
JavaScript在Node.js中的进程管理
开发语言·javascript·node.js
用户47949283569152 小时前
Vite 中 SVG 404 的幕后黑手:你真的懂静态资源处理吗?
前端·vite