本文价值:这篇文章记录的是公司项目里的工程化经验,不是炫 UI。重点在于:在设计稿生成代码质量不稳定、业务链路不断变化的前提下,怎样把一个商家端前端从页面堆叠收口成可维护的 Web / Desktop 一体化工程。
项目背景
这个项目是公司 SaaS 商家端前端,目标是同时支持浏览器 Web 运行和 Electron Desktop 桌面端运行。业务侧涉及登录、门店选择、总部/门店工作区切换、权限菜单、会话恢复、统一请求、CRUD 页面和桌面端打包。
真正的难点不只是“React + Electron 怎么搭”,而是两套运行环境不能互相污染:Web 要能独立构建,Desktop 要能等待本地后端 ready,要能处理窗口、打包和本地能力。页面层不应该到处判断自己运行在哪个端。
1. 先把运行时边界收口
我把运行时识别和接口基址配置放在应用启动阶段处理,而不是散落到每个页面里。
核心思路是:
- 通过
window.electron判断当前是 Web 还是 Desktop; - 启动阶段解析
VITE_WEB_API_BASE_URL、VITE_DESKTOP_API_BASE_URL、VITE_HEYE_API_BASE_URL等基础地址; - Desktop 场景下等待本地后端 ready;
- 统一配置 Axios 客户端,页面只调用业务 API,不关心底层 baseURL。
这样做的好处很直接:运行环境的复杂性被挡在平台层,业务页面不会因为 Web/Desktop 差异变成一堆 if。
2. 登录、门店和工作区状态要可恢复
商家端不是登录后直接进首页这么简单。用户可能有多个门店,也可能存在总部/门店工作区切换,还要处理刷新页面、Token 恢复和权限菜单重新拉取。
这里我更关注状态的权威来源:
- session 负责登录态和运行时;
- users snapshot 负责用户、租户、门店、角色、权限、菜单;
- 登录恢复不能只看本地缓存,还要能重新拿权限信息;
- Web 和 Desktop 的恢复路径要分清,不要互相套逻辑。
这类链路如果只靠页面跳转兜,会越来越乱。必须把“登录态”“用户权限态”“业务工作区态”拆开。
3. UI 生成代码不能直接污染业务层
这个项目早期受 Figma Make 生成代码影响比较大。生成代码可以作为视觉还原参考,但不能直接当长期工程结构。
我的处理方式是逐步收口:
- 业务页面统一靠 Ant Design 和
components/ui基础组件承载; - Dialog、Search、Table、Column Settings、CRUD Hook 这类能力沉淀到公共层;
- 页面只保留业务编排,不把弹窗、表格状态、搜索状态、列配置重复写一遍;
- 对前后端接口保持强契约,不靠空对象、空数组和静默 catch 掩盖协议错误。
换句话说,生成代码可以帮你快一点看到界面,但不能决定项目架构。架构必须服务长期维护。
4. 我从这个项目里沉淀的经验
这个项目让我更明确一件事:前端架构不是目录分得漂亮,而是复杂性有没有被放到正确的位置。
我的默认判断是:
- 运行环境差异,放平台层;
- 登录和权限,放状态与启动链路;
- 请求契约,放 API client;
- 表格和 CRUD,放公共基础设施;
- 页面只做业务组合,不承接所有复杂性。
这比单纯“做了很多页面”更有价值。因为当业务继续长、端继续变、接口继续改时,项目还能继续迭代,而不是每次都靠复制粘贴救火。
总结
SaaS 商家端 Web / Desktop 一体化前端的核心,不是 Electron 壳,也不是某个 UI 库,而是把运行时、会话、权限、工作区、请求和 CRUD 能力收口到稳定边界里。
这也是我想在简历里强调的部分:我不是只会把页面画出来,而是能在真实公司项目约束下,把混乱输入整理成可运行、可维护、可继续扩展的前端工程。