# 前端技术路线评估:Flutter / uni-app / uni-app x | 项目 | 内容 | | --- | --- | | 文档名称 | Continental Retail APP 前端技术路线评估 | | 文档版本 | V1.0 | | 编制时间 | 2026 年 08 月 | | 评估对象 | Flutter · uni-app · uni-app x | | 评估结论 | **推荐 Flutter** | | 外部数据核验日期 | 2026-08-25(来源见附录 A) | 文档控制信息 --- ## 0 结论摘要 **推荐 Flutter。** 这不是"哪个框架更时髦"的偏好问题。四条理由,每一条都可以查证: **第一,架构路线不同,能力上限就不同。** 跨端方案历史上分四条路线,uni-app 走的是"网页套壳",uni-app x 走的是"编译到系统控件",Flutter 走的是"自绘引擎"。这三条路线各有适用场景——**uni-app 系是为"一套代码同时发小程序 + H5 + App"设计的,而这个项目的目标恰恰是把六套小程序关掉,首版只发 Android 和 iOS。** 我们要付它的代价,收不到它的好处。 **第二,这个项目的原生能力密度非常高。** 扫码、VIN 识别、车牌识别、相机、相册、上传进度、定位、权限、弱网离线暂存、崩溃上报、埋点——这些不是画页面,是跟两个操作系统打交道。**这部分工作量不会因为换框架而减少一件。** **第三,生态不在一个量级,而且开放程度的差别在"开到哪一层"。** Flutter 主仓库 **91,171 次提交**,uni-app 主仓库 **11,216 次**,约 8 倍差距;fork 数 31,002 对 3,709,同样约 8 倍。更关键的是:Flutter 从渲染引擎到框架层全部 BSD 开源;uni-app x 的组件和 API 虽然也是 Apache-2.0 开源,**但真正决定 App 能力上限的 Runtime、SDK 和 HBuilderX 是 DCloud 自有知识产权,闭源,没有公开的提交历史。** 落地面同样如此——**字节跳动 90 多款、阿里闲鱼、腾讯、贝壳、美团、京东、携程,公开可查的大厂主力 App 案例集中在 Flutter 一侧;整车厂里 BMW 的 My BMW App 与大众安徽的 ID. UNYX 也是同一条路线,uni-app x 未检索到同等量级的先例**(逐条证据与分档见 [4.3 节](#43-谁在用可查证的落地规模))。 **第四,构建链路和扩展能力受限,而"离线打包"这条退路并不是真正的退路。** 想用加密的付费插件,就只能云端打包;想做 Siri 快捷指令这类扩展,官方要求离线打包——**这两个要求互斥。** 更关键的是:离线打包给到的并不是一个可以随便改的原生工程,而是**围着 DCloud 闭源二进制(一组编译好的 AAR)搭起来的壳**,官方文档要求自定义 `Application` 必须继承 `DCloudApplication`,且写明「App离线SDK不支持Kotlin」。**你只能在壳外面加东西,改不了壳里面的东西。** **成本结论:首版投入两条路线基本持平,差异在 ±10% 以内。** 真正的差异不在首版人天,在**五年后**:需求持续增长、要接更多系统级能力时,一条路线的天花板是自己的工程能力,另一条的天花板是厂商插件市场里有没有人卖这个功能。 | 维度 | Flutter | uni-app | uni-app x | | --- | --- | --- | --- | | 架构路线 | 自绘引擎 | 网页套壳(WebView) | 编译到系统控件 | | 为谁设计 | 需要跨端一致性的独立 App | 小程序为主、App 为辅 | 小程序团队想做 App | | 界面一致性 | 两端逐像素一致 | 受各家 WebView 内核影响 | 用系统控件,两端有差异 | | 嵌 F6 网页 | 通道由 App 侧建立,**F6 零改动** | 同右 | **需 F6 引入 DCloud 的 JS 文件** | | 原生能力开发 | Pigeon 生成三端强类型代码,支持 CLI | 原生插件(已停止新增上架) | UTS 插件,**只能经 HBuilderX,不支持 CLI** | | 开源程度 | 引擎 + 框架全开源(BSD) | 框架层开源(Apache-2.0) | 框架层开源,**Runtime / SDK 闭源** | | 主仓库提交数 | **91,171** | **11,216** | 同左(含在 uni-app 仓库分支) | | 大厂主力 App 落地 | 字节 90+ 款、闲鱼、美团、京东、贝壳、携程、BMW、大众安徽 ID. UNYX | — | **未检索到同等量级公开案例** | | 原生工程归谁 | **自己的工程**,Flutter 挂进去 | DCloud 的壳工程 | **DCloud 的壳工程**,核心是闭源 AAR | | App 扩展能力 | 标准原生开发,无额外规则 | 受限 | **小组件需 Xcode 做 .appex;Siri 需离线打包** | | 接入现有 GitLab 流水线 | 原生支持 | — | 结构性错配 | | 鸿蒙 | 社区分支(3.41 已发布,3.44 预计 9 月) | 支持 | **一等公民**(这一项 uni-app x 更强) | | 包体与内存 | 约多 10MB / 35MB | — | **更小**(这一项 uni-app x 更优,但本项目无包体 KPI) | | 首版成本 | 基准 | — | **±10% 以内,基本持平** | 三条路线总览。uni-app(传统版)几格标"—",是因为它在"界面本质上是网页"这一条上就已经不适合本项目,后续章节重点放在 Flutter 与 uni-app x 的对比。每一行的依据见第 1–5 章,外部数据来源见附录 A。 **表中"包体与内存""鸿蒙"两行是 uni-app x 占优的项,我们主动列出。** DCloud 官方另有一页专门对比 Flutter,客户方检索时大概率会看到——**我们已把那一页逐条核验,结果见[附录 C](#附录-c-对-dcloud-官方对比材料的核验)。** --- ## 1 市面上的跨端方案 ### 1.1 目前可选的技术栈 先把台面上的选项摆全,再谈取舍: | 方案 | 出品方 | 语言 | 首次发布 | 架构路线 | 现状 | | --- | --- | --- | --- | --- | --- | | **原生双端** | Google / Apple | Kotlin · Swift | — | ① 原生 | 平台官方方案,能力无上限 | | **Flutter** | Google | Dart | 2017(1.0 于 2018 年底) | ④ 自绘引擎 | 跨端主流方案,生态最大 | | **React Native** | Meta | JavaScript / TypeScript | 2015 | ③ 编译到系统控件 | 成熟,适合已有 React 团队 | | **uni-app** | DCloud | Vue + JS | 2018 | ② 网页套壳 | 国内多端方案,小程序场景占优 | | **uni-app x** | DCloud | UTS + UVue | 2023 | ③ 编译到系统控件 | uni-app 的原生渲染重构版 | | **Kuikly** | 腾讯 | Kotlin(KMP) | 2025 年 4 月开源 | ③ 编译到系统控件 | 腾讯内部大规模落地,对外生态尚新 | | **Taro** | 京东 | React / Vue | 2018 | ② 网页套壳 | 重心在多家小程序平台 | | **Kotlin Multiplatform** | JetBrains | Kotlin | 2020(2023 年底转 Stable) | 只共享逻辑层 | 逻辑层共享强,UI 层生态尚浅 | | **.NET MAUI** | Microsoft | C# | 2022 | ③ 编译到系统控件 | 微软栈企业适用,国内生态薄 | | **Apache Cordova** | Apache(前身 Adobe PhoneGap) | JavaScript | 2011(PhoneGap 2009) | ② 网页套壳 | 第 ② 条路线的鼻祖,仍维护但重心在兼容性 | | **Ionic Capacitor** | Ionic | JavaScript | 2019 | ② 网页套壳 | Cordova 的现代继任者,Ionic 官方主推方向 | 市面上主要的技术栈选项。「架构路线」一列对应下一节归纳的四条路线——**十一个选项,路线只有四条。** **其余几个为什么不在本次展开,理由逐条写明**,避免"没提到"被读成"没考虑过": | 方案 | 不展开的理由 | | --- | --- | | **React Native** | 与 uni-app x 同属第 ③ 条路线,本文对该路线的分析同样适用;且选它的最大理由——复用既有 React 人力——在本项目不成立 | | **Taro** | 重心是多家小程序平台,而本项目正在关停小程序 | | **Kotlin Multiplatform** | 只共享逻辑层,UI 仍要两端各写一遍;若配 Compose Multiplatform 补 UI,整体成熟度与生态仍明显落后于 Flutter | | **.NET MAUI** | 国内生态与可招聘人力都太薄 | | **Cordova / Capacitor** | 与 uni-app 同属第 ② 条路线且更"裸"。Adobe 的 PhoneGap 已于 2020-10-01 停服;Apache Cordova 仍在维护(2026 年仍有 `cordova-android@15.0.0`、`cordova-ios@8.1.0` 等发版),但工作重心是跟进新版 Android / iOS 的兼容性而非能力演进,`cordova-osx` 与 `cordova-windows` 已停止维护 | | **Kuikly** | 见下——它是这批里最新、也最值得单独回答的一个 | **关于 Kuikly:这是一个技术上认真的方案,不应轻视。** 腾讯于 2025 年 4 月开源,基于 Kotlin Multiplatform,走第 ③ 条路线(原生 UI 渲染),支持 Android / iOS / 鸿蒙 / Web / 小程序 / macOS 六端。**它在腾讯自己内部的落地规模很实在**:官方 README 写明已用于 QQ、QQ 音乐、QQ 浏览器、腾讯新闻、搜狗输入法、应用宝、全民 K 歌、酷狗音乐、酷我音乐、自选股、ima.copilot、微视等产品,内部 20+ 应用深度使用、1000+ 页面、覆盖 5 亿+ 日活。 不选它的三条理由,没有一条是"它不好": 1. **对外开源只有一年多。** 仓库建于 2025-04-24,截至 2026-08-25 共 853 次提交、3,413 star、300 fork。腾讯体系外的生产案例、第三方组件、招聘市场、AI 语料都还没起来。 2. **它的 License 不是标准开源协议。** 条款主体接近 MIT,但加了一条限制:**未经腾讯书面同意,不得为"增加或启用动态代码下发 / 热更新能力"而修改、扩展或制作衍生作品。** 这对本项目不构成实际障碍(我们不做热更新),但它意味着这个项目在治理上不等同于 BSD / Apache 那种无附加条件的开源。 3. **它是给 Kotlin 团队用的。** 本项目原生侧确实要写 Kotlin,但把整个 App 的 UI 层也搬到 Kotlin / KMP,与我方的人力结构和既有技术积累不匹配。 **一句话:Kuikly 值得三年后重新评估,但不适合作为一个 2026 年就要开工、要跑五年的项目的底座。** 至于"腾讯自己都做了 Kuikly,是不是说明 Flutter 不行"——这个问题在 [4.3.3 节](#433-腾讯这一行要单独解释它既用-flutter也做了-kuikly)正面回答。 ### 1.2 归纳:其实只有四条架构路线 上面十一个方案,剥掉品牌和语言的差异,底层只有四条路线。**理解了这四条,就能理解为什么不同方案的能力上限不一样:** ``` ① 原生双端(Native) Android 工程师 ──写一遍──▶ Kotlin ──▶ 安卓系统的按钮 / 列表 / 输入框 iOS 工程师 ──写一遍──▶ Swift ──▶ 苹果系统的按钮 / 列表 / 输入框 → 两套代码、两套人,但系统给什么就能用什么,没有天花板 ② 网页套壳(uni-app、Cordova / Capacitor、Taro) 一套 Vue / React 代码 ──▶ JavaScript ──▶ 系统自带的浏览器组件 ──▶ 渲染成网页 → 一套代码,但用户看到的本质上是个网页; 要用系统能力,得靠"插件"从网页世界打一个洞出去 ③ 编译到系统控件(uni-app x、React Native、Kuikly、.NET MAUI) 一套代码 ──编译──▶ Kotlin ──▶ 安卓系统的原生控件 ──编译──▶ Swift ──▶ 苹果系统的原生控件 → 一套代码,用户看到的是真正的原生控件。 代价:中间那本"翻译词典"必须够全, 词典里没有的东西就做不出来,得自己去补词条 ④ 自绘引擎(Flutter) 一套 Dart 代码 ──▶ Flutter 自带引擎,自己画出每一个像素 ──▶ 屏幕 → 一套代码,不用系统的任何控件,两端画出来完全一样 ``` (Kotlin Multiplatform 是唯一不完全落在这四条里的:它只共享业务逻辑,UI 层仍需各端各写;若配上 Compose Multiplatform 补 UI,则归入第 ④ 条。) 用装修打比方: - **① 原生双端**:请两个装修队分别装两套房子。质量最好,花两份钱,而且两边多半装得不太一样。 - **② 网页套壳**:在两套房子里各贴一层一模一样的壁纸。快、便宜,但墙还是人家的墙——墙有多平,壁纸就有多平。 - **③ 编译到系统控件**:拿同一张图纸,翻译成两家各自的材料清单,再让两个装修队照做。比贴壁纸结实得多。**但图纸上画了个东西、翻译词典里没这个词,就做不出来。** - **④ 自绘引擎**:自己带整套施工队和材料进场,从水泥开始砌。不管进的是哪套房子,装出来完全一样。 ### 1.3 四条路线的能力上限不一样 这是本章最重要的一句话,也是后面所有结论的地基: | 路线 | 界面一致性 | 系统能力的获取方式 | 能力天花板由谁决定 | | --- | --- | --- | --- | | ① 原生 | 差(两端天然不同) | 直接调 | **无天花板** | | ② 网页套壳 | 差(受内核影响) | 靠插件从网页打洞出去 | **插件生态有没有人做** | | ③ 编译到控件 | 中(用系统控件) | 靠"翻译词典" + 插件 | **词典覆盖度 + 插件生态** | | ④ 自绘引擎 | **最好(逐像素一致)** | 自己写原生插件直接调 | **自己的工程能力** | 四条路线的对比。最后一列是本项目最该关注的:**②③ 的天花板在别人手里,④ 的天花板在自己手里。** 一个五年周期的业务系统,需求只会越加越多。天花板在谁手里,是个战略问题,不是技术偏好。 --- ## 2 Flutter 与 uni-app / uni-app x 的对比 上一章讲了四条路线。这一章说清楚这三个具体方案分别是哪条路线、为谁设计、适合什么。 ### 2.1 uni-app:第 ② 条路线,为小程序团队设计 **它是什么**:用 Vue 写代码,在 App 端跑在系统自带的浏览器组件里。 **它为谁设计**:DCloud 的出发点非常明确——让**已经在做微信小程序的前端团队**,用同一套 Vue 代码顺便发一个 App 和一个 H5。 **它适合什么场景**:主战场是小程序、App 只是顺带的项目。比如一个商城,微信小程序是主入口,App 只是给老客户的一个补充。这类项目 uni-app 的价值非常大。 **它不适合什么**:App 是主战场、且需要大量系统能力的项目。因为界面本质上是网页,要用相机、要扫码、要后台上传,都得靠插件从网页世界打洞出去。 ### 2.2 uni-app x:第 ③ 条路线,是 uni-app 的重构版 **它是什么**:用一门叫 UTS 的新语言写,编译成安卓的 Kotlin、苹果的 Swift、鸿蒙的 ArkTS,渲染用真正的系统原生控件。 **必须澄清一点:uni-app 和 uni-app x 不是同一个东西的两个版本,是两套不同的技术底座。** 它们共享品牌、共享 IDE、共享很多写法,但底层是重写的。一个直接证据:**uni-app x 不支持传统 uni-app 的原生插件,而那批旧原生插件已经停止接受新增上架。** 即使在 DCloud 自家体系内做版本迁移,插件也要重写。 **设计思想值得肯定**:UTS 直接编译成 Kotlin 和 Swift,比"字符串方法名 + 弱类型参数"的传统桥接方式要优雅得多。**这一点应该如实承认。** **它为谁设计**:还是那批小程序团队,只是这次要把 App 端做得更像原生。 **它的约束在哪**:见 1.3 那张表的第 ③ 行——能力天花板取决于"翻译词典"的覆盖度和插件生态。词典里没有的、插件市场上没人卖的,就得自己用 UTS 补,而补这件事又受工具链约束(第 5 章)。 ### 2.3 Flutter:第 ④ 条路线,为独立 App 设计 **它是什么**:Dart 代码提前编译成机器码,界面由 Flutter 自带的引擎逐像素绘制,不使用系统的任何控件。 **它为谁设计**:出发点就是**做一个正经的 App**,而不是"顺便也发一个 App"。 **这带来两个结构性结果**: 1. **界面完全脱离系统控件的差异** —— 同一套设计规范在 Android 和 iOS 上落地的结果逐像素一致。 2. **原生能力靠标准插件机制直接对接** —— 每个能力封装成独立插件包,接口用官方工具从一份定义文件生成 Dart / Kotlin / Swift 三端强类型代码,改了接口忘记同步实现,**编译期就报错**。要什么能力就自己写,不用等插件市场。 ### 2.4 三者的定位对照 | | uni-app | uni-app x | Flutter | | --- | --- | --- | --- | | 架构路线 | ② 网页套壳 | ③ 编译到系统控件 | ④ 自绘引擎 | | 原始设计目标 | 小程序团队顺便发 App | 小程序团队把 App 做好一点 | 做一个独立的正经 App | | 主平台 | 小程序 / H5 | 小程序 / H5 / App | **App** | | 界面一致性 | 弱 | 中 | **强** | | 系统能力获取 | 插件打洞 | UTS 插件 + 翻译词典 | **自写原生插件,直接调** | | 能力天花板 | 插件生态 | 词典 + 插件生态 | **自己的工程能力** | | 适合本项目吗 | 否 | 部分适合 | **适合** | 三个方案的定位差异。最后一行的判断依据在第 3 章。 ### 2.5 架构层面的结论 **这个项目要做的是一个独立 App,不是一个小程序的附属品。** 它的目标是把六套微信小程序整合掉、关停,首版只发 Android 和 iOS,不发小程序、不发 H5、不发鸿蒙。也就是说: > **uni-app 系最值钱的能力——"一套代码同时发小程序、H5 和 App"——在这个项目里没有买家。** 我们要承担它为了多端兼容而付出的所有架构代价(能力天花板受制于插件生态、工具链绑定、构建方式受限),却收不到它最大的那份好处。 **单从架构选型的角度,在这个项目上 Flutter 已经胜出。** 后面三章是把这个结论落到具体的业务需求、生态数据和工程链路上。 --- ## 3 技术评估:结合本项目的业务需求 > 这一章写给技术评审。 ### 3.1 嵌入 F6 网页与双向通道 —— 本项目最高风险项 这个 App 里最核心的几条业务链路——报价开单、施工查车、结算收银,以及整个提醒模块——是把 F6 的网页嵌进 App 里承载的。这些网页需要调用 App 的能力(扫码、拍照、相册、带进度的上传、拨号、获取登录态与门店上下文、原生弹窗、跳转原生页等,共 13 项能力、15 个方法),App 也要能反向通知网页。 ``` 【Flutter 方案】F6 页面不需要任何改动 ──────────────────────────────────────────────── F6 的网页 │ window.ContiBridge.call('scan', { mode: 'barcode' }) │ ▲ │ └── 这段胶水代码,由 App 在页面加载完成时自动注入 ▼ 单一双向通道(JavaScript Channel) │ ▼ App 的 WebView 容器 ──▶ 原生扫码 / 相机 / 上传 一条通道,双向,收发同一套协议:{ id, method, params } 【uni-app x 方案】F6 页面必须先引入 DCloud 的 JS 文件 ──────────────────────────────────────────────── F6 的网页 │ ⚠ 必须先引入: