今年圈子里聊开发,几乎绕不开 Vibe-Coding 这个词。给它一个不那么玄的解释:你把需求用自然语言讲清楚,AI 负责把代码生成出来,开发者负责拆需求、验结果、修边界,整个过程像顺着节奏走一样。真正让我改观的是手头一个需要同时覆盖 H5、iOS、Android、小程序和桌面端的项目——五端协同这件事,我用这套方式完整跑了一轮。
最初我以为 AI 顶多帮我写几个页面组件,做完才发现,Vibe-Coding 最大的价值,是把“五端协同”这种原本很重的工程活,压缩成一个人也能推进的流水线。前提是流程里的坑你得提前知道,尤其是“同一份代码凭什么五个端都能跑”这件事,远比想象中容易翻车。这篇文章不聊概念,只聊我实际操作里的选型、步骤、踩坑和完整排查链路,适合正在做多端产品、又想让 AI 帮忙提效的开发者参考。
1. 五端协同到底要协同什么
1.1 先给“五端”画个边界
我这边项目的五端,分别是 H5(浏览器里打开的网页)、iOS 端、Android 端、小程序端和桌面端(电脑上安装的客户端)。不同团队对五端的定义可能略有出入,有的把电视端、车机端也算进来,但不管怎么划分,工程上的问题都一样:同一个产品,要跑在几个运行环境差异极大的宿主里。
先把每端的特点列一下,后面所有的选择,几乎都从这张表出发:
| 端 | 典型形态 | 我最关注的差异 |
|---|---|---|
| H5 | 浏览器打开 | 无安装、路由是浏览器历史、登录走网页授权 |
| iOS | iPhone/iPad 上的原生应用 | 刘海安全区、系统权限、应用商店审核 |
| Android | 各品牌安卓机上的应用 | 设备碎片化、返回键行为、各厂商 ROM |
| 小程序 | 平台 App 内运行 | 包体积限制、页面栈机制、平台审核 |
| 桌面端 | Windows/macOS 上的客户端 | 多窗口、托盘、快捷键、本地能力 |
这张表看起来都是“平台常识”,但它决定了协同的边界。五端协同不是让五个端长得一模一样,而是让业务语义在五个端完全一致,同时允许交互形态随端变化。用户在手机上习惯左滑返回,在电脑上习惯点关闭按钮,这些差异不该被“统一”抹掉。
1.2 协同的本质是共享层与差异层的边界
做五端最怕两件事:一是同一套业务逻辑在五个端各写一遍,改一个规则要改五处;二是为了统一而强行抹掉平台特色,结果每个端用起来都别扭。协同的意义,是前者尽量收敛、后者尽量保留。
所以我给工程画了两条线。共享层放的是跟端无关的东西:登录态与用户信息、请求封装与错误处理、全局状态、主题变量、通用业务组件(比如订单卡片、空态页)。差异层放的是每个端自己的东西:入口文件、路由注册方式、支付拉起方式、系统权限申请、安全区处理、本地存储实现。
这个边界的价值在于:AI 生成的代码归位到哪一层,是可以写进约束条件的。只要分层规则清楚,AI 就能在共享层写出“任何端都可运行”的代码,在差异层写出“这一端专用”的代码,而不是把浏览器 API 和原生 API 混在一起。这也是我后面踩过最大一个坑的根源,先留个悬念。
2. Vibe-Coding 为什么适合扛这种多端工程
2.1 先纠正对 Vibe-Coding 的误解
很多人把 Vibe-Coding 理解成“让 AI 一把梭把所有代码写完,人只负责看结果”。我实际跑下来的感受完全不是这样。它更像一种协作节奏:你把一个足够小的任务用自然语言描述清楚,AI 给出代码,你立刻编译、运行、验证,发现偏差再让 AI 修正,如此循环。人的核心工作不是敲键盘,而是拆任务、定约束、验结果。
为什么这个节奏特别适合五端项目?因为五端工程的复杂度主要不在“写代码”本身,而在同一套需求的端侧差异管理。让 AI 从空文件开始一次性生成一个完整五端应用,基本不现实;但让它一次生成一个模块、一个页面、一个适配器,再靠人的检查把偏差收回来,是完全可以跑通的。换句话说,Vibe-Coding 不是让 AI 替你干活,而是让你把活拆到 AI 能接住的大小。
2.2 AI 在五端项目里最省时间的三个环节
第一个环节是骨架生成。共享层的请求封装、状态管理、主题变量、通用组件,这些代码模式高度重复,AI 一次生成一整套,比我手写快得多,而且命名风格可以统一,后面维护起来省事。
第二个环节是平台差异的对照翻译。比如登录流程,AI 很擅长把“H5 走授权跳转、小程序走平台凭证、原生端走系统授权、桌面端走回调”这种差异描述,翻译成各端适配器代码,它甚至能主动列出我没想到的边界情况,比如“用户在桌面端未安装浏览器时怎么处理授权回调”。
第三个环节是报错甄别。五端联调时经常出现“同一份代码,有的端报这个错、有的端报那个错”的情况,把几段报错丢给 AI 找共性,往往比人肉翻文档快。尤其是在报错信息被各端包装得五花八门时,AI 的横向对比能力是实打实的效率。
2.3 给 AI 的提示词模板:把约束讲清楚,比把需求讲清楚更重要
用 Vibe-Coding 做多端项目,提示词里最值钱的部分不是“帮我实现购物车”,而是边界约束。我一般用固定模板:
[角色] 你是一名熟悉跨端开发的前端工程师 [背景] 这个项目同时输出 H5 / iOS / Android / 小程序 / 桌面端 [任务] 实现订单列表页面,包含分页、空态、下拉刷新 [约束] 共享层代码禁止调用 window/document/localStorage 等宿主专属 API; 所有端侧差异必须走 adapter,不允许在业务代码里写 if 判断平台; 时间戳统一用服务端返回字符串展示,不要自行格式化; 失败状态要有统一错误提示 [输出] 给出每个文件的路径、代码,以及每个文件一句话说明这套模板跑下来的经验是:AI 不是能力不够,而是边界不清。你不说“共享层禁止宿主 API”,它就真敢在共享层里写 localStorage;你不说“差异走 adapter”,它就真会把平台判断散落在业务代码里。把约束写清楚,AI 生成的代码能少返工一大半。另外我还会加一条固定要求——让 AI 在代码注释里显式声明“这段代码假设存在哪些宿主环境能力”,这条后面救过我一次。
3. 五端底座的搭建流程:从空目录到五端可跑
3.1 框架选型的逻辑:先想清楚“AI 对哪个方案最熟”
跨端工程的第一件事是选框架。目前主流方案大致分两类:一类是编译到各端原生页面的声明式框架,写出来是组件化、声明式的前端语法,最终各自编译成对应端可运行的结构;另一类是自绘渲染引擎类方案,用同一套渲染层画界面,适合动画、图表、图形重交互的产品。
我选了前一类,核心原因有三个:第一,这类框架的社区体量大,AI 训练语料里这类代码极多,生成质量明显更高;第二,我自己和队友更熟前端写法,共享层代码维护门槛低;第三,原生能力可以靠插件机制补齐,遇到框架没覆盖的能力,还能写各端原生代码兜底。自绘渲染类方案在复杂动画场景确实更强,但对 AI 生成代码的准确率要求更高,小团队从零起步阶段我不太推荐。
选型还有一个容易被忽略的点:团队的长期维护能力。AI 生成的代码,最终还是要人来回改的。如果团队里没人看得懂某套方案的底层机制,一旦 AI 生成的东西出问题,排查成本会高到离谱。选“大家都能接住”的方案,比选“纸面参数最强”的方案更实际。
3.2 目录结构:共享层必须从第一天就独立出来
框架选完,第二步是目录结构。我一开始没太在意,直接把所有代码按页面堆在一起,结果 AI 生成第二个页面时,就把上一个页面的样式和工具函数复制过去了,返工好几次。后来改成下面这种结构,问题立刻少了很多:
project/ ├─ shared/ # 共享层:请求、鉴权、状态、主题、通用组件 │ ├─ api/ # 接口定义与请求封装 │ ├─ store/ # 全局状态 │ ├─ theme/ # 主题变量、安全区变量 │ └─ components/ # 通用业务组件 ├─ web/ # H5 入口与浏览器适配 ├─ ios/ # iOS 壳与原生插件 ├─ android/ # Android 壳与原生插件 ├─ miniapp/ # 小程序入口与页面栈适配 └─ desktop/ # 桌面端入口与窗口适配AI 生成代码时,我会在提示词里明确“文件落在哪一层”。请求封装属于 shared/api,页面属于各端自己的目录,适配器属于对应端目录。目录分得越清楚,AI 的归位就越准确。这里有个小技巧:让 AI 在输出代码时附带文件路径,并严格要求“不得在 shared 层引用各端目录里的文件”,从根源上切断跨层污染。
3.3 分步生成骨架:一次只让 AI 做一个模块
搭建底座时最容易犯的错,是让 AI 一口气生成“整个项目”。我实操下来的顺序是:第一轮先让 AI 生成目录结构和 shared 层的主题变量、请求封装;第二轮生成全局状态与登录态管理;第三轮生成通用组件;最后一轮才生成各端的入口和路由。每一轮生成完都立刻编译一次,把报错当场反馈给 AI 修正。
这么做的原因是,AI 生成代码的出错率跟任务粒度强相关。任务越小、上下文越明确,一次通过率越高。等骨架全绿了,再开始做具体业务页面,后面的速度会快很多,因为大部分通用能力已经就位,AI 只需要顺着已有模式填页面。我实测下来,同样是做一个订单列表,骨架搭好之后 AI 一次生成通过率,能比从零生成翻一倍还多。
4. 端侧差异才是真战场:五端适配的实操记录
4.1 路由与导航:五套行为,一张路由表
骨架搭好后,第一个撞上的差异是路由。H5 靠浏览器前进后退,小程序用自己的页面栈和跳转限制,桌面端是多窗口模型,双端原生则各自维护导航栈。如果每个端自己写路由,跳转逻辑很快就乱。
我的做法是在 shared 层维护一张声明式路由表:页面路径、参数、是否带 tab、是否需要登录态。各端写一个很小的 adapter,把自己的导航能力接到这张表上。业务代码只调用统一跳转方法,不关心底层是浏览器历史还是页面栈。这个设计让 AI 抄作业变得特别简单:它只需要照着表加一行,再在各端 adapter 里补对应页面的注册,完全不用理解五套导航机制的细节。
4.2 登录、支付与安全区:共享业务语义,差异放适配器
登录是另一个典型。五个端的登录动作完全不同,但登录成功后的业务语义一样:拿到用户身份、换取访问令牌、刷新用户状态。我在 shared 层只暴露一个 login 方法,入参是平台标识和凭证,由各端 adapter 分别实现凭证获取:H5 走网页授权跳转,小程序走平台登录凭证,原生端走系统授权,桌面端走浏览器回调。后端统一验签换令牌。这样共享层从不知道登录发生在哪个端。
支付也是同样的思路。端侧只负责拉起支付和接收结果,订单创建、金额校验、回调验签全部放服务端。共享层不出现任何平台支付 SDK 的痕迹。安全区则更细碎:iPhone 的刘海、小程序的胶囊按钮、桌面窗口的标题栏拖拽区,我都抽象成主题变量,AI 生成组件时被要求一律读变量,不许写死数值。
4.3 键盘、剪贴板这类“小差异”也不能放过
除了路由、登录、支付这些大块头,还有一堆容易被忽略的小差异。比如输入框弹键盘时,H5 和原生端的页面压缩行为不同;复制剪贴板,桌面端还要考虑用户明确授权;文件选择,浏览器走上传控件,原生端走系统文件选择器。
这些小差异的特点是:平时不触发,一旦触发就是体验事故。我的处理方式是照旧推进 adapter,比如封装一个统一的 clipboard 接口,各端自己实现。同时我会要求在 prompt 里带上一条固定约束——“凡是涉及系统能力的调用,先列出这个能力在五个端分别用什么 API 实现,再写代码”。AI 一旦先列清单再动手,遗漏的比例会明显下降。
4.4 一份差异对照表,既是开发依据也是 AI 提示词素材
实操中我养成了一个习惯:开工前先写一页五端差异对照表。比如:
| 能力 | 端侧差异 | 统一方案 |
|---|---|---|
| 路由 | 浏览器历史/小程序页面栈/多窗口 | shared 路由表 + 各端 adapter |
| 登录 | 授权跳转/平台凭证/系统授权 | 统一 auth 服务换令牌 |
| 支付 | 各平台支付 SDK/回调 | 服务端统一订单与验签 |
| 安全区 | 刘海/胶囊/标题栏 | 主题 token 统一暴露 |
| 存储 | 浏览器/原生/小程序各不相同 | storage adapter 封装 |
这张表不仅是给团队看的,更是给 AI 看的。每轮对话开始前,我会把相关行贴进提示词,AI 生成的适配代码准确率明显上升。差异管理做到这个程度,五端协同才真正有了抓手。
5. 一次五端白屏事故的完整排查链路
5.1 现象:三个端正常,两个端白屏
项目跑到中后期,我加了一个消息中心功能。代码写完在桌面端验证正常,又顺带看了下 H5,也正常,于是直接提交了五端回归。结果 H5、小程序、桌面端都正常,iOS 和 Android 两个端一进去就白屏。iOS 控制台报“某全局对象为 undefined”,Android 端报的是“类型错误:无法读取某属性”。
两个报错词不一样,我最初以为是两端各自的问题,差点分头去查。冷静下来想了一下:这两个端唯一的共同点是都跑原生容器,都吃同一份 shared 层代码。问题大概率出在共享层,而不是端侧。这也是五端项目的一个好处——多端一起出问题,本身就是一种定位线索。
5.2 排查过程:从现象到根因的完整链路
我先把 shared 层的初始化日志加到了两端的最前面,发现两端的崩溃发生在模块加载阶段,连业务页面都没进。这就缩小了范围:要么是某个模块加载时抛异常,要么是模块间循环依赖。
接着用排除法定位。shared 层有几个基础模块:请求封装、存储封装、状态管理、工具函数。我先在入口处临时注释掉存储封装,两端恢复正常;再单独恢复存储封装的初始化,两端立刻崩。问题锁定在存储模块。
打开那个文件一看,原因其实很典型:AI 在生成统一存储接口时,用了浏览器环境里的 localStorage 作为兜底实现,而原生容器里根本没有 window 对象,模块一加载就抛错。H5 端之所以没问题,恰恰因为它跑在浏览器里,这个浏览器专属假设被完美地藏了起来,没有报错、没有警告,直到原生端才爆炸。
5.3 修复与复盘:让环境假设显式化
修复并不复杂:把宿主能力按端拆进 adapter,shared 层只留存储接口,H5 用浏览器存储实现,原生端用原生存储实现,小程序用平台自己的存储实现。改完后五端回归全部通过。
但这次事故给我的最大教训,不是“AI 写错了代码”,而是“AI 写出了一端能跑、四端跑不了的代码,并且没有任何提示”。它让我意识到,凡是 AI 生成的共享层代码,必须要求它显式声明我做了哪些环境假设。后来我把这条直接写进提示词约束,再遇到类似问题,AI 会主动说这段代码假设存在 window 对象,我就能在 review 阶段提前拦下来,而不是等五端回归时炸。
6. 发布、自动化与长期维护:把 Vibe-Coding 流程固化下来
6.1 分端配置与一键打包
五端项目跑顺之后,每天面对的就是版本发布。我的做法是把环境配置全部收敛到按端的配置文件里,dev、test、prod 三套环境参数各写各的,接口域名、渠道号、埋点开关都在配置里管理,禁止在业务代码里散落环境判断:
common: apiBase: https://api.example.com timeout: 8000 web: apiBase: https://api.example.com/web native: pushEnabled: true desktop: autoUpdate: full打包阶段用脚本编排各端构建命令,一条命令触发五端产物生成。小程序端要特别注意包体积限制,我按页面和公共模块做了分包,AI 生成页面时会顺带输出资源占用说明,超标的提前处理。原生端的证书签名和桌面端安装包更新机制,属于各自发布渠道的事,我放到构建机上统一处理,本地开发环境不碰签名,避免密钥泄露。流程固化以后,五端同时发版从半天压缩到了半小时。
6.2 AI 维护存量代码的三个规矩
项目进入维护期后,用 AI 改老代码反而比写新代码更容易出问题。我给自己定了三个规矩。
第一,一次只让 AI 改一个点。请它修改某个页面时,明确写出只允许动哪些文件,不允许顺手优化其他文件。AI 很容易在改 A 的时候把 B 的样式也调了,合并时根本发现不了。第二,先让 AI 输出改动清单再落地。凡是涉及 shared 层的改动,要求 AI 先列影响面,说明会波及哪几个端,再决定是否合并。第三,回归前让 AI 生成一份本次改动涉及的端侧 API 清单,拿着清单去跑对应端的真机验证,比盲目全量回归省时间。
6.3 最后说点个人体会
做完这一整轮五端协同,我最大的感受是:Vibe-Coding 真正值钱的不是生成代码的速度,而是它逼着我把需求结构化了。给 AI 写的每一段提示词,本质上都是在梳理业务边界;维护的五端差异对照表,既是给 AI 的上下文,也是团队最实用的文档。
我现在每个新需求开工前,都会先花半小时把五端差异清单更新一版,再让 AI 动手,特别是顺手把环境配置和路由表一并核对。这半小时看起来是额外成本,实际能省下后面好几个小时的 debug 时间。如果你也在用 AI 辅助开发做多端项目,建议你先别急着让它写页面,先把共享层和差异层的边界画清楚,把环境假设写进约束,再开始顺着感觉走——这大概就是 Vibe-Coding 做五端协同最靠谱的打开方式。