Files
conti-docs/tech-selection/Flutter-vs-UniApp.md
T
Guangfei.Zhao ee4146b121 Add new BMW and VW asset images to tech-selection
- Added bmw1.png, bmw2.png, bmw3.png, bmw4.png, bmw5.png to tech-selection/assets
- Added vw1.png, vw2.png, vw3.png, vw4.png, vw5.png to tech-selection/assets
2026-08-26 11:09:51 +08:00

962 lines
84 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端技术路线评估: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 做 .appexSiri 需离线打包** |
| 接入现有 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 | 20171.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** | 腾讯 | KotlinKMP | 2025 年 4 月开源 | ③ 编译到系统控件 | 腾讯内部大规模落地,对外生态尚新 |
| **Taro** | 京东 | React / Vue | 2018 | ② 网页套壳 | 重心在多家小程序平台 |
| **Kotlin Multiplatform** | JetBrains | Kotlin | 20202023 年底转 Stable) | 只共享逻辑层 | 逻辑层共享强,UI 层生态尚浅 |
| **.NET MAUI** | Microsoft | C# | 2022 | ③ 编译到系统控件 | 微软栈企业适用,国内生态薄 |
| **Apache Cordova** | Apache(前身 Adobe PhoneGap | JavaScript | 2011PhoneGap 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 的网页
│ ⚠ 必须先引入:<script src="uni.webview.1.5.5.js">
│ uni.webView.postMessage({ data: {...} })
<web-view @message> (网页 → App,单向)
uni.createWebViewContext(id).evalJS("...") App → 网页,另一条单向通道)
两条独立的单向通道,方向不对称
```
**事实**DCloud 官方 `web-view` 组件文档原文):网页要向 App 发消息,需要**"在网页中引入 uni.webview.1.5.5.js"**,再调 `uni.webView.postMessage()`App 向网页发消息走 `evalJS()`,本质是执行一段 JavaScript 字符串。
**推论**:这意味着 **F6 这家第三方厂商,需要修改他们的页面,引入 DCloud 提供的 JS 文件**。Flutter 方案下胶水代码由我们在 App 侧注入,**F6 一行都不用改**。
F6 是这个项目里影响面最大的外部依赖——销售全链路、整个提醒模块、以及非马牌商品的采购供货都压在它上面。**在这条链路上再叠一个"需要对方配合改造"的前置条件,是排期风险,不是技术偏好。**
两点补充,避免结论被过度解读:
- 这不是说 uni-app x 做不出 JSBridge。做得出,但要在两条不对称的单向通道之上,自己封装请求 ID、超时、就绪信号、错误处理、方法白名单这一整套;Flutter 的单一双向通道天然就是这个形状。
- `evalJS()` 传大量数据要额外处理序列化和转义,上传进度这类高频事件走这条路需谨慎设计。
### 3.2 原生能力密度:本项目的决定性变量
| 能力 | 用在哪 |
| --- | --- |
| 扫码(条码 / 二维码) | 扫码入库、扫码查件、商品与库位 |
| VIN 识别 | 条码形式 + 印刷字符 OCR,端上完成 |
| 车牌识别 | 拍照上传走云端 OCR,需先压图 |
| 相机 | 检测报告、装车视频、鉴定证据 |
| 相册多选 | 证据上传、营业执照 |
| 文件上传(带进度) | 大文件、弱网场景 |
| 图片压缩 | 上传前必须压,否则弱网传不动 |
| 拨号 | 客服、门店联系 |
| 定位 | 扫码入库以地图定位为准 |
| 运行时权限申请 | 相机、相册、定位,含拒绝后的引导 |
| 弱网离线暂存与幂等重传 | 断网本地存,恢复后批量提交且不重复 |
| 崩溃上报原生桥 | Bugly 只有原生 SDK |
| 埋点 SDK 接入 | 神策 |
| 安卓物理返回键拦截 | 嵌网页时不拦截会导致填一半的表单丢失 |
| WebView 文件选择器 | 网页里的 `<input type="file">` |
| iOS 隐私清单 | 苹果强制要求,没有直接被拒 |
本项目需要的原生能力清单。门店场景(地下车库、仓库、施工区)网络条件差,而恰恰是这些场景要传大文件——弱网相关的几项不是可选项。
**这张表是全文成本结论的支柱。** 它说明这个项目的工作量重心本来就压在原生能力和系统集成上,"画页面快不快"能省下的比例有限。而上面每一项,在 uni-app x 下都是一个要自己写、自己维护、自己在两端分别验证的 UTS 插件——**数量不会因为换框架而减少一件。**
**Flutter 侧**:扫码这一个原生实现,同时服务 App 内的扫码页和嵌入网页的通道调用,**一份实现两个调用方**,不需要复制两套。
**uni-app x 侧**:UTS 插件的设计思想更优雅,但**按官方文档,UTS 插件目前只支持通过 HBuilderX 创建和使用,不支持通过命令行使用**——后果见第 5 章。
### 3.3 崩溃上报与埋点
业务方指定了两个工具:崩溃用**腾讯 Bugly**,错误明细和埋点用**神策**。账号现成、合规口径已过,这个前提不因技术选型而改变。
| | Flutter | uni-app x |
| --- | --- | --- |
| **神策** | 官方发布的插件,在公开包管理平台上,有认证发布者、有版本号 | **不在插件市场**。官方说明因缺少 UTS 的压缩混淆方案暂未提供市场包,需**联系技术顾问索取 zip 源码包**;另有后端版本下限要求 |
| **Bugly** | 只有原生 SDK,需自建原生桥(几十行 Kotlin/Swift) | 未见官方支持,需完全自行用 UTS 封装 |
两个指定 SDK 的支持成熟度对比。
**两边都有工作量**,差别是 Flutter 侧有一项是公开发布、可版本化管理、有官方发布者背书的现成包;uni-app x 侧两项都是定制的,且其中一项脱离了公开的市场分发渠道——后续升级、问题追溯、责任归属都要靠人对人沟通,而不是查版本记录。
对一个要跑五年的系统,**"崩溃上报本身不能再出问题"** 是硬要求。
### 3.4 十九个模块并行开发时,边界怎么守住
这个项目 19 个业务模块、近三百条需求,会有多人并行开发很长时间。工程上最容易出问题的不是某个功能写不出来,而是**模块边界慢慢烂掉**——A 模块图省事直接引用了 B 模块的内部类,半年后想改 B 就动不了了。
**Flutter 方案**:用 Melos 组织 monorepo,21 个包按职责拆开(基础设施层 / 业务模块层 / 原生能力层),依赖规则由 Dart 的包机制**在编译期物理强制**——业务模块 A 根本 import 不到业务模块 B 的任何符号,不靠代码规范或口头约束。想复用组件,只能提到公共层。
**uni-app x 侧**同样可以做工程化拆分,但约束强度依赖团队自觉和评审纪律,缺少编译期的物理阻断。
这一条在项目初期看不出价值,在第二年会。
### 3.5 渲染性能、包体与内存(明确标注:非决定项)
Flutter 用自绘引擎、Dart 提前编译成机器码;uni-app x 编译成原生控件调用。**两者在这个项目上都够用**——这是一个以表单、列表、报表为主的业务 App,不是游戏,也不是有复杂动效的消费级产品。
**拿性能说事经不起追问,我们不把它算进结论。** 列在这里只是让对比完整。
**包体与内存这两项,Flutter 确实更高,我们主动列出。** DCloud 官方对比页给出的实测是:安装包 18M 对 8.5M、内存占用约 138MB 对 103MB。**这两个数字我们认为是可信的**——自绘引擎要把渲染引擎打进包里,这是路线本身的代价,不是实现问题。
但它在本项目不构成决策变量:这是一个**门店员工使用的内部业务 App**,通过企业分发和应用商店安装,不参与消费级 App 的下载转化竞争,没有包体 KPI,也没有"多 10MB 就少一批用户"的场景。设备是门店配发的作业终端,35MB 内存差异在现代机型上不产生可感知影响。
需要一并说明的是,**uni-app x 走离线 / 嵌入这条路同样有包体增量**:按 DCloud 官方数字,iOS 约 8.7 MB、Android(仅 arm64-v8a)约 8.1 MB。这项对比的完整核验见[附录 C](#附录-c-对-dcloud-官方对比材料的核验)。
真正和体验相关、且在本项目真实存在的差异是**视觉一致性**:这个 App 要把六套来源不同、不同团队不同时期做的小程序整合成一个东西。整合最大的隐性风险不是功能缺失,而是同一个业务概念在不同页面上叫法不同、长得不同、操作方式也不同——用户会觉得"这还是六个东西,只是塞进了同一个壳子"。Flutter 逐像素自绘,同一套设计规范落地结果完全一致;uni-app x 用系统控件,安卓的按钮和苹果的按钮本来就不一样,要抹平需要额外工作。
### 3.6 小结
| 本项目的关键维度 | Flutter | uni-app x | 差异是否决定性 |
| --- | --- | --- | --- |
| 嵌入 F6 网页 + 双向通道 | 通道由 App 侧建立,F6 零改动 | 需 F6 引入 DCloud 的 JS 文件 | **是** |
| 十几项原生能力 | 三端强类型生成,支持 CLI | UTS 插件,只能经 HBuilderX | **是** |
| Bugly + 神策 | 神策有官方发布包 | 神策需单独索取;Bugly 无官方支持 | 较强 |
| 19 模块的工程边界 | 编译期物理强制 | 靠规范与评审 | 中等 |
| 视觉一致性 | 逐像素一致 | 需额外抹平 | 中等 |
| 渲染性能 | 够用 | 够用 | **否** |
| 包体与内存 | 约多 10MB / 35MB | 更小 | **否**(内部业务 App,无包体 KPI) |
七个维度的逐条对照。最后两行特意列出,是为了说明我们没有把不构成差异的项算进结论里,也没有回避对方占优的项。
---
## 4 生态、社区、落地规模与 AI 工具链
这一章比大多数人以为的重要。**技术栈的生命力不看今天能做什么,看社区每天往里投入多少。**
### 4.1 开源程度:关键在"开到哪一层"
先澄清一个容易说错的点:**uni-app x 不是闭源的。** 它的组件和 API 大部分以 Apache-2.0 协议开源,在 `dcloudio/uni-app` 仓库的 `uni-app-x` 分支里。
**但开源的层次不一样,这才是要害:**
| | Flutter | uni-app x |
| --- | --- | --- |
| 框架层(组件、API | 开源(BSD-3-Clause | 开源(Apache-2.0 |
| **渲染引擎 / Runtime** | **开源**,在主仓库内 | **闭源**DCloud 自有知识产权 |
| **原生 SDK** | 不适用(原生层完全由项目自己掌握) | **闭源** |
| **开发工具(IDE** | 无绑定,任意编辑器 + 官方 CLI | **HBuilderX,闭源,且插件开发离不开它** |
开源层次对比。DCloud 的许可协议明确写明:内嵌的 Runtime 或 SDK 知识产权仍归 DCloud 所有。
**这意味着什么:** 当你遇到一个渲染层或运行时的 bug,Flutter 侧你可以读引擎源码、定位、提 issue、必要时自己 fork 修;uni-app x 侧你只能提工单等厂商。对一个五年周期的核心业务系统,这是两种完全不同的风险敞口。
### 4.2 社区活跃度:实测数据
| 指标 | Flutter | uni-app | 倍数 |
| --- | --- | --- | --- |
| 主仓库提交数(默认分支) | **91,171** | **11,216** | **约 8.1 倍** |
| Fork 数 | **31,002** | **3,709** | **约 8.4 倍** |
| Star 数 | 178,643 | 41,600 | 约 4.3 倍 |
| 仓库创建时间 | 2015-03 | 2018-07 | — |
| 开源协议 | BSD-3-Clause | Apache-2.0 | — |
GitHub 实测数据,核验于 2026-08-25,取自 `flutter/flutter``dcloudio/uni-app`
**口径要说明白,不做诛心解读:** star 数反映的是全球开源关注度,不等于国内商业项目的落地数量。uni-app 在国内企业应用、商城、政企项目里的落地量非常大,这一点数据体现不出来。
**但有一条差异是数据也遮不住的:** Flutter 的 91,171 次提交**包含了渲染引擎在内的全栈**;DCloud 的 11,216 次提交是**框架层的**,而真正决定 App 能力上限的 Runtime 和原生 SDK **闭源、没有任何公开的提交历史**
也就是说,真实的工程投入差距**比 8 倍这个数字看起来还要大**——因为对方最核心的那部分,外界根本看不到,也无法参与。
**另一个可查证的信号是平台连续性。** DCloud 在 App 端已经换过三代方案:5+ 应用 → nvue(基于修改过的 Weex 渲染引擎,而 Apache Weex 已于 2021 年 5 月退役、6 月仓库归档)→ uni-app x。DCloud 官方文档已说明 **nvue 和 5+ 的官方维护在 2024 年停止,建议迁移到 uni-app x**
对比 Flutter:2015 年至今同一条主线持续演进,没有让用户推倒重来过。**这是"平台连续性"的差异,会直接变成五年后的迁移成本。**
### 4.3 谁在用:可查证的落地规模
提交数说明的是"投入",落地案例说明的是"验证"。这一节回答一个很实际的问题:**同等体量、同样要做一个正经 App 的团队,实际上选了什么。**
**先把证据分档,不混着用:**
| 档次 | 是什么 | 可信度 |
| --- | --- | --- |
| **甲** | 框架方官方发布的案例页或官方仓库 / 文档 | 最高,可点开核对 |
| **乙** | 使用方自己公开发布的材料——技术团队实践文章,或官网依法披露的第三方 SDK 清单 | 高,但要看发表年份 |
| **丙** | 第三方对应用商店安装包的 SDK 扫描统计 | **只能证明"包里有",不能证明"整个 App 都是它写的"** |
证据分档。以下每一条都标注了档次和年份,**丙档只用来看趋势,不用来下结论。**
#### 4.3.1 中国主流 App 的实际选择
| 使用方 | 涉及的 App / 业务 | 跨端技术栈 | 证据 |
| --- | --- | --- | --- |
| **字节跳动** | **90 多款**应用:抖音火山版、飞书 Lark、Coze、掘金、Lemon8、小荷健康、幸福里等 | **Flutter** | **甲** — Flutter 官方中文站开发者故事,2026-06-22 更新 |
| **阿里巴巴** | **闲鱼**(已推进到线上主链路) | **Flutter** | **甲** — Flutter 官方 Showcase;闲鱼团队并开源了 FlutterBoost、Fish Redux 等基建 |
| **腾讯** | 官方页表述为"多个团队将应用完整迁移到 Flutter" | **Flutter** | **甲** — Flutter 官方 Showcase「腾讯」页:调试效率 +80%、90% 代码多端复用、开发工作量 −33% |
| **腾讯**(另一条产品线) | QQ、QQ 音乐、QQ 浏览器、腾讯新闻、搜狗输入法、应用宝、全民 K 歌、酷狗、酷我、自选股、ima.copilot、微视 | **Kuikly**(自研,KMP | **甲** — 官方 README:内部 20+ 应用深度使用、1000+ 页面、覆盖 5 亿+ 日活 |
| **贝壳找房** | 主业务多平台 | **Flutter** | **甲** — Flutter 官方 Showcase2021-03 |
| **大众汽车(安徽)** | **ID. UNYX App**:购车定制、车联车控、社区、商城 | **Flutter** | **乙(第一方合规披露)** — 大众安徽官网《第三方个人信息共享清单》列明 Flutter SDK,使用情形写作「App 所有的 L1、L2、L3 页面开发语言」 |
| **美团** | 外卖**商家端** App | **Flutter**(自建 MTFlutter 生态) | **乙** — 美团技术团队官方博客:Flutter 覆盖商家端 **90% 以上业务**,团队 **90% 以上成员**具备 Flutter 开发能力(2021-03 |
| **携程** | 主 App:火车票、酒店等十多个核心业务的列表页与主流程 | **原生 + React Native + Flutter 混合** | **乙** — 携程技术《携程 APP Native/RN 内嵌 Flutter UI 混合开发实践和探索》(2021-10)、《Flutter 在携程复杂业务的高性能之旅》(2022-04) |
| **京东** | **JDFlutter**:2017 年起调研,物流 App 验证,后由技术中台建容器 / 工具链 / 组件平台 | **Flutter** | **乙** — 京东 EMOP 官方文档《JDFlutter 白皮书》、京东云开发者社区 |
| **百度** | 百度贴吧 | **Flutter** | **乙,但年份较早** — GMTC 2019 深圳站百度工程师公开分享。**未检索到 2024 年之后的官方更新,这一条只作历史参考** |
国内主流 App 的跨端技术栈。凡是检索不到近年官方更新的,都已就地标注。
**这张表能读出三件事:**
**① 主流选择高度集中在 Flutter。** 阿里、字节、美团、京东、贝壳、携程、大众安徽——公开材料指向同一个方案,腾讯也有官方案例在列(它同时另有一条 Kuikly 自研线,见 4.3.3)。React Native 在携程这类 2015–2018 年就大规模投入的团队里仍是重要存量,但**新增投入基本都流向 Flutter**(这一点在 4.3.5 的第三方统计里能再次看到)。
**② 落地形态几乎都是"原生为主 + Flutter 承载业务模块",不是整个 App 用跨端框架重写。** 携程写的标题就是"Native/RN 内嵌 Flutter UI";闲鱼是先用 FlutterBoost 做混合栈再逐步推进主链路;京东是从物流 App 起步再建中台;美团覆盖到 90% 的是**商家端**,不是 C 端主 App。
> **这个形态和本项目的规划完全一致。** 我们本来就要写十几个原生插件、要嵌 F6 的网页——Flutter 负责业务页面和统一体验,系统能力仍走原生。**换句话说,本项目的架构不是一个需要自己趟的新形态,而是这批团队已经趟了五六年的成熟形态。**
**③ 没有一家把 uni-app 系用在自己的主力 App 上。** 这一条要说得公平:**这不是 uni-app 的缺陷,是定位不同。** uni-app 的主战场是中小企业、政企项目和以小程序为主的多端场景,那里它的落地量非常大,也确实解决问题。但本项目的参照系是"做一个独立的、原生能力密集的主力 App"——在这个参照系里,可查证的大规模先例都在 Flutter 一侧。
#### 4.3.2 单独看一类:整车厂的 App
把 BMW 和 ID. UNYX 拎出来单独讲,理由是技术上的:**这一类 App 的能力构成,是"原生能力密集"这件事的极端形态。** 远程车控、实时车况回传、车辆查找与远程摄像头、充电桩与地图——全部要落到系统 API 和车联网长连接上,且对时延和可靠性有硬要求;与此同时,它们还要在多个品牌、多个市场上维持同一套体验。**第 ④ 条路线(自绘引擎)能不能扛住"重原生 + 多变体 + 长周期"这个组合,这两个案例是目前能查到的最直接的回答。**
##### BMWMy BMW App(甲档,Flutter 官方 Showcase 收录)
BMW 的起点和很多团队一样:iOS 与 Android 各有一套 BMW Connected / MINI Connected**两端的功能和设计逐渐分叉,到 2018 年已经大到必须收敛。** 选型时团队评估了多个跨端框架,为了用户体验**明确排除了基于浏览器的方案**(即第 ② 条路线),最终选定 Flutter。
| 节点 | 事实 |
| --- | --- |
| 2018 年 | 确认双端分叉问题,启动跨端方案评估 |
| 2019 年 10 月 | 慕尼黑工程会议敲定方案 |
| **2020 年 7 月** | **My BMW App 上线——从定案到发布不到一年** |
| 覆盖范围 | **47 个国家、五大洲**iOS + Android 双端合一,同时服务 BMW 与 MINI 两个品牌 |
| 工程化 | 内部 **Mobile 2.0 Platform**,每天出多个构建,**每个构建自动生成、测试并部署 96 个变体** |
| 2021 年 10 月 | **每个 App 变体已累计构建超过 10,000 个版本** |
| 团队结构 | 按域拆分:一个团队做车辆连接与通信抽象层,若干团队做共享应用平台,更多团队做面向客户的功能与实验特性 |
BMW 在 Flutter 官方 Showcase 页公布的时间线与工程数据。
![My BMW App 车况首页](assets/bmw1.png)
My BMW App 的车辆首页:车况总览、剩余电量与续航、锁车 / 解锁 / 灯光 / 鸣笛的快捷车控,以及车辆查找与远程摄像头入口。
![My BMW App 使用场景](assets/bmw2.png)
车内使用场景。这类 App 的主干功能建立在定位、推送与车联网长连接之上,是典型的原生能力密集型应用。
> **这个案例真正的价值不在"BMW 也用 Flutter",而在那个 96。** 一个构建自动产出 96 个变体、每个变体累计上万次构建,说明 Flutter 的产物在 CI 里是可批量、可自动化、可长期滚动的——**这正是第 5 章要谈的构建链路问题**。对照 uni-app x 的云端打包(每次计费、加密插件强制走云端、自定义基座需重制),这种量级的自动化在那条路线上很难成立。
原文引述 BMW 集团 Offboard Platform 副总裁 Dr. Nicolai Kraemer 的表述:新的应用平台建立在三根支柱之上——**易用性、安全性与可靠性**(英文原文 "user friendliness, safety and reliability")。对一个要跑五年的企业级 App,这三个词恰好就是选型时该问的三个问题。
##### 大众汽车(安徽):ID. UNYX App(乙档,第一方合规披露)
这一条的证据类型和上面不同,**但可信度不低**:大众安徽官网的《第三方个人信息共享清单》里列有 **Flutter SDKGoogle LLC**,使用情形一栏直接写作**「App 所有的 L1、L2、L3 页面开发语言」**——L1 / L2 / L3 是该 App 自己的页面层级口径,即一级、二级、三级页面,合起来就是全部主干界面。**这是依据个人信息保护法规必须如实披露的材料,不是市场稿**,属于使用方在法定披露文件里自陈的技术栈。
ID. UNYX App 的功能面覆盖得相当宽,五张官方商店截图覆盖了它的主要板块:
![ID. UNYX — 官方资讯](assets/vw1.png)
资讯与转化:品牌 / 车型资讯流(精选 · 车型 · 去玩 · 资讯),页内嵌预约试驾、定制与下单、购车权益等入口。
![ID. UNYX — 互动社区](assets/vw2.png)
社区:UGC 内容流,分最新 / 关注两条线,右侧为话题聚合。
![ID. UNYX — 在线定购](assets/vw3.png)
车型与配置:与众 06 / 07 / 08 / 09 切换,展示续航、加速等参数,底部为预约试驾与定制下单。
![ID. UNYX — 车联车控](assets/vw4.png)
车控:车辆状态(续航、电量、停泊状态)、车锁 / 车窗 / 后备箱 / 鸣笛 / 闪灯的快捷车控、温度调节与附近充电站。**这一页是纯原生能力密集页,且对实时性有要求。**
![ID. UNYX — 精品商城](assets/vw5.png)
商城:商品分类、Banner 轮播、新品推荐列表——标准的电商页面结构。
> **需要如实补一句:同一站点的另一份 SDK 说明里还列有 React Native SDK。** 也就是说 ID. UNYX 同样是混合形态,并非 100% Flutter。**这一点不削弱结论,反而印证了 4.3.1 的第 ② 点**——真实世界里的大型 App 几乎都是混合的,问题从来不是"能不能只用一个框架写完",而是"主干页面交给谁"。**在这个案例里,主干页面交给了 Flutter。**
##### 这两个案例回答了本项目的三个疑问
1. **重原生能力是不是 Flutter 的禁区?** —— 不是。远程车控、实时车况回传、车联网长连接的原生密度高于本项目的扫码 / 车牌 OCR / 定位 / 推送,而且可靠性要求是安全级的。
2. **多变体、长周期的工程化扛不扛得住?** —— BMW 每个构建自动出 96 个变体、每个变体累计上万次构建,已经给出了上限参考。
3. **是不是必须整个 App 重写成 Flutter** —— 不是。这两个案例都是"原生 / 混合底座 + Flutter 承载主干页面",与本项目规划的形态一致。
#### 4.3.3 腾讯这一行要单独解释:它既用 Flutter,也做了 Kuikly
上表里腾讯出现了两次。这是评审会上很可能被追问的一点,先讲清楚:
- **腾讯是超大体量公司,几十条产品线各自做技术选型,本来就不会只有一个答案。** Flutter 官方 Showcase 收录了腾讯案例,同时 QQ 系走自研的 Kuikly——**两件事同时为真,不矛盾。**
- **Kuikly 解决的核心问题是动态化。** 它的 License 里唯一那条附加限制,就是禁止为"增加或启用动态代码下发能力"制作衍生作品——**这从反面说明了动态下发是这个框架最要害的能力。** 对 QQ、QQ 音乐这类月更、要灰度、要快速止血的消费级 App,热更新是刚需。
- **而本项目的发版链路已经定了**:安卓走托管 OTA 分发页,iOS 走 TestFlight + App Store,都是正规链路;企业侧的安全评审通常也不倾向接受"可以绕开商店直接下发代码"这种能力(同[附录 C](#补充一条对方的真实优势热更新)对热更新的判断)。**驱动腾讯自研 Kuikly 的那个核心动机,在本项目并不存在。**
**所以"腾讯自己不全用 Flutter"不能反推成"Flutter 不行"。** 它反推出的是另一件事:**当一家公司的需求足够特殊,它会自己造轮子——而这条路只有腾讯这个体量的团队走得起。** 我们不是那个体量,本项目也没有那个特殊需求。
#### 4.3.4 字节跳动:目前公开信息中规模最大的单一使用方
数据来自 Flutter 官方中文站的开发者故事,2026-06-22 更新:
- **90 多款 Flutter 应用**在线上运行
- **800 多名 Flutter 开发者**,并设有专职的 Flutter Infra 基建团队
- 点名的产品包括:抖音火山版、飞书 Lark、Coze、小荷健康、幸福里、Lemon8,以及技术社区 **掘金**
原文对收益的表述,出自字节跳动 Flutter 基础设施团队负责人董岩:**「与原生双端开发相比,Flutter 为我们的团队节省了大约 1/3 的开发时间」**。
> **这个 1/3 必须标清口径:它的对照组是"原生双端",不是 uni-app。** 拿它去论证"Flutter 比 uni-app x 省 1/3"是错的,我们不这么用。本文档的成本结论仍然是第 6.1 节那句——**首版两条路线基本持平**。这里引用它只说明一件事:一个有能力自研全套基建的团队,在做过 90 多个 App 之后仍然选择继续投入 Flutter。
顺带一提:**这份评估里引用的技术社区"掘金",它自己的 App 就是 Flutter 写的。**
#### 4.3.5 第三方统计:只看趋势,不下结论
移动分析平台 Appfigures 通过扫描应用安装包内的 SDK 特征做过框架分布统计。**这是丙档数据**——只能证明"这个包里检出了某框架",不能证明整个 App 都由它写成(按 4.3.1 的第 ② 点,大厂 App 恰恰大多是混合的)。两组数字:
| 口径 | 数据 | 时间 |
| --- | --- | --- |
| 新上架应用中检出该框架的比例 | **Flutter 约 11.07%**、React Native 约 6.75%2022 年分别为 10.15% / 4.73% | 2024 年 110 月 |
| 非游戏类 iOS 应用 Top 10,000 中的检出数 | React Native **1,350** 个、Flutter **1,184** 个;框架相关下载量占比 RN 47%、Flutter 38% | 2025-12 |
Appfigures 的两组框架分布数据。
**这两组数字方向相反,但并不矛盾,反而说明了问题的实质:**
- **存量看 React Native。** 它 2015 年就开源,比 Flutter 1.02018 年底)早三年多;Top 10,000 这种榜单本身就偏向存量大厂应用。
- **增量看 Flutter。** 新上架应用里 Flutter 的检出比例接近 RN 的 1.6 倍,且 2022 → 2024 两年间差距还在扩大。
**这正好印证 4.3.1 的观察**——用 React Native 的大多是历史投入,新的投入在往 Flutter 走。同一份统计里还有一条:**Cordova 与 Ionic 呈持续下降趋势**,这是第 ② 条路线(网页套壳)在国际市场的整体走向。
**必须补一句口径说明,否则这组数据会被误用:uni-app 系不在这类统计的框架清单里。** 原因不是它不重要,而是它的主体落地在国内小程序和 H5,不通过 App Store / Google Play 分发,这套方法论本来就扫不到。**口径不可比的数字我们不拿来对比,也不拿它去论证任何结论。**
#### 4.3.6 uni-app x 侧:未检索到同等量级的公开案例
**我们未检索到 uni-app x 在大厂主力 App 上的公开落地案例。** 这里写"未检索到"而不是"没有"——DCloud 官方公布的是 uni-app 全系的开发者与应用总量,那个数字很大,但它统计的主体是小程序和 H5,无法单独拆出"用 uni-app x 做的独立 App"有多少、规模多大。**口径不可比的数字我们不拿来对比。**
### 4.4 AI 工具链:开放生态 vs 厂商内置
这是这次特别关注的一项。**先说清楚:两边都有官方 AI 工具,不能说 uni-app x 没有。**
| | Flutter / Dart | uni-app x |
| --- | --- | --- |
| 官方 skills | `flutter/agent-plugins``dart-lang/skills`,**独立开源仓库** | 内置在官方 `uni-agent` 助手中 |
| 官方 MCP 服务 | Dart & Flutter MCP server | `uni-app-x-mcp` |
| 能用在哪些工具上 | Claude Code、Codex、Cursor、Antigravity 等,**装到哪个 agent 都行** | 主要围绕自家生态与少数几个工具 |
| 安装方式 | `npx skills add flutter/agent-plugins --skill '*'`,**一行命令** | 随官方助手提供 |
| 能否自己改 / 自己加 | **可以,仓库开源,可 fork 可 PR** | 受限于官方提供 |
双方 AI 工具链对比。Flutter 的 skills 是**任务粒度**的,官方文档与 2026-05-06 的发布公告合计已列出十项以上,覆盖生成单元测试、生成集成测试、统计测试覆盖率、配置多语言、构建响应式布局、配置声明式路由、实现 JSON 序列化、解析包依赖冲突、修复静态分析错误、使用模式匹配等,仓库持续新增。
**两个真实的差别:**
**① 开放 vs 内置。** Flutter 的 skills 是独立开源仓库,一行命令装进任意 AI 编程工具,团队可以 fork 它、按自己的规范改它、往里加自己项目的 skill。uni-app x 的 AI 能力主要绑在官方助手和自家 IDE 里——**这和第 5 章要讲的工具链绑定是同一个问题的两面。**
**② 语料深度。** AI 生成代码的准确率和这门语言在公开代码里的沉淀量强相关:
- **Dart / Flutter**:近十年公开代码沉淀在 GitHub 上,全球范围,各种项目形态都有。
- **UTS / UVue**:新语言,语料以中文官方文档为主,体量小得多。而且插件市场的付费插件是**加密分发**的——这些代码根本不会进入任何公开语料。
**这一条对 2026 年的实际开发效率有直接影响。** 同一个开发者,用 AI 辅助写 Flutter 和写 UTS,产出质量和返工率不是一回事。
### 4.5 这一章对本项目意味着什么
生态不是"锦上添花"的加分项,它决定四件很实际的事:
1. **遇到问题能不能自己解决** —— 引擎开源你能读能修,闭源你只能等工单。
2. **五年后还有没有人维护** —— 8 倍的提交量差距 + 三代方案换代史,指向两种不同的平台连续性。
3. **有没有人趟过同样规模的路** —— 字节的 90 多款线上应用、闲鱼的主链路、美团商家端的 90% 覆盖、携程的原生 + Flutter 混合栈、京东的 JDFlutter 中台、BMW 每个构建 96 个变体的自动化产线、ID. UNYX 用 Flutter 承担全部主干页面,意味着我们会遇到的坑大概率已经有人踩过并写下来了。**尤其是"原生为主 + Flutter 承载业务模块"这个形态——那正是本项目要走的路。**
4. **AI 辅助的效率** —— 直接落在代码量最大的那两块工作上。
---
## 5 构建、发布与可扩展性
这一章是 uni-app 系限制最集中的地方,也是最容易在项目中后期才暴露出来的地方。
### 5.1 我们已经定下来的工程链路
- GitLab CI/CD 流水线,带 lint、格式化、测试的卡点
- dev / uat / prod 三套环境构建
- iOS 由一台远程 Mac 出包,后续注册成流水线的构建节点
- 内测分发:安卓走托管的 OTA 分发页,iOS 走 TestFlight
这套链路的核心诉求是**全自动、可追溯、可复现**:任何一个版本,都能从一次 git 提交自动构建出来,不依赖任何人的本机环境。
### 5.2 插件工具链绑定图形化 IDE
按 DCloud 官方文档原文:
> **"目前仅支持通过HBuilder X 创建和使用UTS插件,不支持通过cli的方式使用UTS插件"**
**一个绑定图形化 IDE 的插件工具链,和一条要求全自动的流水线,是结构性错配。** 这不是"配置一下就好"——它意味着构建链路里存在一个必须有人打开 IDE 点按钮的环节。
普通的 uni-app x 页面本身可以自动化打包,问题集中在原生插件这一环。而由 3.2 节可知,**这个项目的原生插件不是一两个,是十几个。**
### 5.3 云端打包与离线打包:两条路各有硬约束
uni-app x 提供两种出包方式:
| | 云端打包 | 离线打包 |
| --- | --- | --- |
| 构建在哪 | DCloud 的云端服务 | 自己的 Android Studio / Xcode |
| 原生工程可定制范围 | 无 | **只能改外壳,改不了内核**(见下) |
| 能否用加密的付费插件 | **是** | **否** |
| 计费 | 每次 2 元;60MB 以下不额外收费,超出按档加收 | 免费 |
两种出包方式的约束对比。第二行最容易被误读,下面单独展开。
#### "离线打包 = 原生工程完全可控"是一个误解
离线打包确实会给你一个 Android Studio / Xcode 工程,**但这个工程的核心是 DCloud 已经编译好的闭源二进制。** 按官方文档,Android 侧要引入的是一组 AAR`lib.5plus.base-release.aar``uniapp-v8-release.aar``utsplugin-release.aar` 等,**没有源码**。
| 你能改的(外壳) | 你改不了的(内核) |
| --- | --- |
| 包名、版本号、图标、启动图 | 页面怎么渲染 |
| Gradle 依赖、ABI、SDK 版本 | 页面容器与生命周期 |
| AndroidManifest / Info.plist 权限项 | UTS 与原生之间的通信机制 |
| 在壳外面加自己的原生模块、加 App Extension | 运行时的任何行为 |
离线打包的可改 / 不可改边界。右列全部封装在编译好的二进制里,不提供源码,也没有修改入口。
**而且连这个"外壳"本身都是被规定死的**,以下两条都是官方文档原文:
- **自定义的 `Application` 必须继承 `DCloudApplication`**,新建工程默认的 `MainActivity` 节点必须移除 —— 换句话说,**宿主工程的入口不归你,归它**。你不是"把 uni-app 集成进自己的 App",是"在它的 App 里放自己的东西"。
- **「App离线SDK不支持Kotlin」** —— 2026 年一个安卓工程不支持 Kotlin,意味着你自己要补的那部分原生代码得退回去用 Java 写。
**uni-app x 用的还不是上面这套**,它有独立的一套原生 SDK。按官方文档,该 SDK 当前**"仅支持VDOM模式,蒸汽(Vapor)模式的SDK还未发版"**——**也就是说,走离线 / 嵌入这条路,拿不到它最新的那套渲染模式。** 集成后的包体增量:iOS 约 8.7 MBAndroid(仅 arm64-v8a)约 8.1 MB。
> **所以准确的说法不是"离线打包可以定制",而是:你拿到的是一个必须围着闭源运行时搭起来的壳工程——能在壳外面加东西,不能改壳里面的东西。** 一旦需求落在"改壳里面",这条路就是死的,且没有第二个人能帮你改,因为源码不公开。
对照 Flutter:原生侧就是一个标准的、完整的 Android / iOS 工程,`Application``Activity``AppDelegate` 全部是自己的代码,Flutter 以模块形式挂进去,而不是反过来。要写 Kotlin 写 Kotlin,要写 Swift 写 Swift,没有第二套规则。
#### 一个二选一的死结
**回到上面那张表里的两个"否"**
- 官方文档明确:**"uts加密插件只支持云端传统打包,不支持离线打包、也不支持安心打包"**
- 而下一节会看到,一些 App 扩展能力(如 Siri 快捷指令)**官方建议的实现路径要求离线打包**
**推论:如果项目既用到了加密的付费插件,又需要做需要离线打包才能实现的扩展能力,这两个要求互斥,无解。** 到那时的选择只剩下:放弃扩展能力,或者花钱重新买一套非加密授权(如果厂商提供的话),或者整体迁走。
另外两条商务上的绑定,也都来自官方文档:
- 付费插件的授权**绑定唯一的 appid 和包名**,官方原文:「如购买者更换了这 2 个信息中的一个,需要重新购买授权」
- 试用版只能用于自定义基座,**不能用于正式发布**
**补充一条口径,避免夸大:** 云端打包每次 2 元、最高档也就每次几十元,**相对项目总投入完全可以忽略,这个数字不值得拿来做文章。** 这一节的问题不是钱,是构建方式被约束住之后带来的连锁限制。
### 5.4 App 扩展能力的天花板
这是最容易被低估的一块。**App 的形态远不止"页面 + 接口"**,一个用五年的 App 迟早会碰到这些需求:
- 手机桌面小组件 / 锁屏小组件(门店当日待办、库存预警一眼可见)
- 接入系统语音助手(Siri 快捷指令、App Intents
- 系统级的多媒体推送、本地进度通知(比如上传进度显示在通知栏)
- 分享扩展、通知服务扩展等各类 App Extension
对照 uni-app x 官方文档的现状:
| 扩展能力 | uni-app x 现状 |
| --- | --- |
| iOS 桌面小组件 | **没有内置 API**。需在 Xcode 里用 SwiftUI + WidgetKit 做成 `.appex`,放进 UTS 插件的 `app-ios/Plugins/`,再配 `nativeResources/ios/ios-extension.json` 和描述文件;HBuilderX 4.61+ 的云端打包才支持携带 |
| Siri 快捷指令 / App Intents | **仅靠 UTS 插件无法实现**。官方建议:离线打包的原生工程里实现 `AppShortcutsProvider`,再用 UTS 插件衔接业务逻辑 |
| 其它 App Extension | 非内置能力,走上面同一条路径 |
uni-app x 的扩展能力现状,取自 DCloud 官方文档。
#### 安卓侧同样如此:一个桌面小组件的真实交付清单
上表是 iOS 侧,容易被理解成"苹果比较特殊"。**实际上安卓侧是一样的。** 下面这份清单来自社区一篇 2026-05 的 UTS 插件实战教程(**注明:这是社区一手实战记录,不是官方文档**),做的就是一个安卓桌面待办小组件,最终要交付的东西是:
| 交付物 | 内容 |
| --- | --- |
| **三个 Kotlin 文件** | `TodoWidgetNative.kt`(业务)、`TodoWidgetProvider.kt``AppWidgetProvider`)、`TodoListRemoteViewsService.kt`(列表数据源) |
| **AndroidManifest 注册** | receiver 声明 + service 声明,service 需带 `BIND_REMOTEVIEWS` 权限 |
| **三个 XML 布局** | 小组件主布局、列表项布局、空态布局 |
| **UTS 桥接层** | `interface.uts` + `index.uts`,且导出类型"必须使用 `type` 而非 `interface`" |
一个安卓桌面小组件在 uni-app x 下的实际交付物。
**除了这些代码本身,工具链还额外强加了三条成本,这才是关键:**
- 原文写明:**「每次修改这些文件后必须重新制作自定义基座」**——也就是说,改一行 XML 布局都要重新走一遍自定义基座的制作流程;只有纯 UTS / UVue 的改动才走差量编译。**这在标准安卓开发里就是一次普通的增量编译。**
- **不能直接 import `R` 类**取资源 ID,要用 `getIdentifier()` 在运行时按字符串查找——编译期的类型检查在这里失效了。
- 出现 `index.kt` 找不到、`R$id.class` 冲突这类报错时,需要手动清掉 `unpackage/cache/` 再重来。
**落点:安卓侧同样要写 Kotlin、同样要碰 AndroidManifest 和 XML 布局。** 而且断了之后不是回到干净的原生开发——是回到原生开发,再加上一个"每改一次就重打基座"的循环。
**这里要把话说准,不能说"做不到"——做得到,但代价是三层的:**
1. **你最终仍然要打开 Xcode 写 Swift、打开 Android Studio 写 Kotlin。** "一套代码跨端"的承诺在这里就断了,而且是两端一起断。
2. **在此之上还要额外绕一遍 DCloud 的打包体系**——配 `ios-extension.json`、处理描述文件、每改一次原生文件重做一次自定义基座、在云端打包和离线打包之间做取舍。这是标准原生开发里不存在的额外一层。
3. **而官方给出的那条"离线打包"退路,本身就是 5.3 里那个受限的壳工程**——`Application` 得继承 `DCloudApplication`、传统离线 SDK 不支持 Kotlin、运行时闭源不可改。它不是一条干净的原生开发通道,只是一个开口更大一点的口子。
> 一句话概括:**你既要会 Swift 和 Kotlin,又要额外学一套 DCloud 的插件与打包规则,最后还只能在别人的壳外面加东西。**
相比之下,Flutter 项目的原生侧就是完整、开放、自己说了算的 Xcode 和 Android Studio 工程,做扩展就是标准的原生开发,没有第二套规则要学,也没有改不动的黑盒。
**这正好回到 1.3 节那张表的最后一列:能力天花板在谁手里。**
### 5.5 小结
| 工程维度 | Flutter | uni-app x |
| --- | --- | --- |
| 插件开发能否命令行化 | 能 | **不能,绑定 HBuilderX** |
| 接入现有 GitLab 流水线 | 原生支持 | 存在必须人工介入的环节 |
| 原生工程归谁 | **自己的工程**Flutter 以模块挂进去 | **DCloud 的壳工程**,自己的东西放进去;`Application` 须继承 `DCloudApplication` |
| 运行时能否排查 / 修改 | 引擎开源,可读可改 | **闭源二进制(AAR),不可改** |
| 宿主原生代码语言 | Kotlin / Swift,无限制 | 官方原文:**「App离线SDK不支持Kotlin」** |
| 加密付费插件与离线打包 | 不适用 | **互斥** |
| 桌面小组件 / Siri 等扩展 | 标准原生开发 | **两端都要写原生**Swift + Kotlin)+ 额外绕打包体系 + 每改一次原生文件重做自定义基座 |
| 构建是否经第三方云 | 否,全在自有流水线 | 云端打包方式下需要 |
工程链路对比。倒数第一行对有正式安全评审流程的企业是需要走流程回答的问题,不是一句"没事的"能带过的技术细节。
---
## 6 结论
### 6.1 成本:首版工时不会差很多
先把成本拆开,才能判断换框架到底影响哪一块:
| 成本构成 | 占比区间 | uni-app x 相对 Flutter |
| --- | --- | --- |
| **业务逻辑与外围系统集成、联调** | 约 45–55% | 基本无差异(跟框架无关) |
| **UI 实现** | 约 20–25% | 略省(Vue 熟悉度高) |
| **原生能力与桥接** | 约 1015% | 明显更贵 |
| **工程、CI、发布、可观测** | 约 1015% | 明显更贵 |
首版投入的成本构成与相对差异。占比区间是基于本项目形态的估算,不同团队会有出入,但量级关系是稳定的。
```
占比 uni-app x 的影响
────────────────────────────────
业务集成 45-55% ───── 无差异
UI 实现 20-25% ↓ 略省 ← 它的优势只作用在这一块
原生桥接 10-15% ↑ 更贵 ←┐
工程 CI 10-15% ↑ 更贵 ←┘ 它的额外成本作用在这两块
```
**uni-app x 的效率优势作用在占比第二小的那一块,而它的额外成本作用在另外两块。** 一加一减,**首版总投入差异在 ±10% 以内,可以认为基本持平。**
这句话给得干脆,不留模糊:**成本不是选择 Flutter 的理由,也不是选择 uni-app x 的理由。**
### 6.2 五年视角:这才是真正的差异
首版持平,但这个系统要跑五年,需求只会越加越多。**那就把时间轴拉长,两边各回看五年。**
**Flutter 这五年(2020 → 2026):**
从一个不被看好的新框架,长成跨端开发的主流选择。今天主仓库 178,643 star、31,002 fork、91,171 次提交,引擎到框架全部开源。同时它支持以模块形式嵌入已有的原生 App,意味着它既能做整个 App,也能作为某条业务流嵌进别人的 App 里——**这是一条向上兼容、路越走越宽的路线。**
需要说明的是,原生开发并没有消失,平台特性、系统扩展这些活仍然要写原生——**而这恰恰和本项目的情况吻合:我们本来就要写十几个原生插件。**
**DCloud 这五年:**
同一时期换了三代 App 方案——5+ 应用、nvue(基于修改过的 Apache Weex 引擎,而 Weex 本身已于 2021 年 5 月从 Apache 孵化器退役、6 月仓库归档),到现在的 uni-app x。**官方已说明 nvue 和 5+ 的维护在 2024 年停止,建议迁移到 uni-app x。**
**这不是攻击,这是可查证的平台连续性记录。** 一边是同一条主线持续演进十一年、没让用户推倒重来过;一边是每隔几年换一代底座、并要求存量项目迁移。**站在 2026 年选一个要用到 2031 年的技术栈,这条记录应该被正面评估。**
### 6.3 厂商投入与治理结构
| | Flutter | uni-app x |
| --- | --- | --- |
| 主导方 | Google + 全球开源社区 | DCloud 一家公司 |
| 可见的工程投入 | 91,171 次公开提交,含引擎 | 11,216 次公开提交,**Runtime/SDK 闭源无公开记录** |
| 极端情况下的退路 | BSD 开源,可自行 fork 维护 | **没有第二个可以接手的主体** |
治理结构对比。这是风险管理问题,不是产品好恶问题。
### 6.4 推荐 Flutter
四条理由收口:
**① 架构路线就决定了适用性。** uni-app 系是为"小程序 + H5 + App 多端复用"设计的,而这个项目正在关掉那六套小程序、首版只发两个平台。**它最值钱的能力在这里没有买家,我们只承担代价。**
**② 本项目原生能力密度高,这部分工作量不会因换框架而减少。** 十几项原生能力要逐个实现、逐个在两端验证。Flutter 在原生桥接、指定 SDK 接入、以及与既有流水线的契合度上都更成熟,而 uni-app x 的效率优势只作用在占比约两成的 UI 实现上。
**③ 生态与开放程度不在一个量级。** 8 倍的公开提交量差距,加上"Flutter 引擎开源、uni-app x Runtime 闭源"这个层次差异——决定了遇到底层问题时,一边能自己解决,一边只能等厂商。
**④ 能力天花板归属不同。** Flutter 的天花板是我们自己的工程能力;uni-app x 的天花板是厂商插件市场和打包体系。**五年周期里,这一条的复利效应最大。**
### 6.5 公平地说,uni-app x 强于 Flutter 的三点
这一节不能省。一份只说对方缺点的评估,在技术评审面前站不住。
**① 鸿蒙支持目前确实更完整。这一条要说得精确,分三层:**
- **对 uni-app x 有利的部分,如实写明:** UTS 可直接编译成鸿蒙的 ArkTS,鸿蒙在它这里是一等公民路径。而 Google 已经明确**不会在 Flutter 主线支持鸿蒙**——官方仓库里那条鸿蒙适配 issue(#150536)的处理结果是 **Closed as not planned**。这不是"还没做",是"不打算做"。
- **但差距在收窄:** 鸿蒙侧的 Flutter 适配由 OpenHarmony-SIG 的社区分支承接,**2026 年 1 月已成立 Flutter SIG 做治理**,按季度跟进主线版本;目前 **3.41 的鸿蒙版已发布,3.44 的鸿蒙版预计 2026 年 9 月**。它不是一个无人维护的野生 fork。
- **对本项目的具体含义:** 我们的版本基线正是 **Flutter 3.44.9**,对应的鸿蒙版下个月就到。**鸿蒙不在本项目首版范围内**,而我们刻意停在 3.44.9 没追最新版,本来就是为后续接鸿蒙留兼容窗口。所以这条差距在本项目的时间线内是可控的。
**结论仍然是:如果鸿蒙将来变成硬需求,uni-app x 在这一项上更省事,应当如实计入。** 只是它比"Flutter 做不了鸿蒙"要小得多。
**② 小程序与 H5 的复用能力是真实存在的。** 将来若又有"同一套业务同时发 App 和小程序"的需求,它的价值会立刻显现。本项目用不上,但这是它客观的长处。
**③ UTS 这门语言的设计思路是对的。** 它直接编译成 Kotlin 和 Swift,比传统那种"传一个字符串方法名 + 一包弱类型参数"的桥接方式干净得多,方向上是正确的。**我们对 uni-app x 的保留意见不在语言设计,在它外面那层工具链和打包体系**——第 4、5 章列的问题,没有一条是 UTS 语言本身造成的。
以上三点是**能力层面**的长处。另外还有三项 uni-app x 占优、但不属于能力范畴的:**包体更小、内存占用更低、支持热更新**——这三项连同 DCloud 官方对比材料的逐条核验一并放在[附录 C](#附录-c-对-dcloud-官方对比材料的核验)。
### 6.6 如果最终选择 uni-app x,需要先落实的六项前提
如果业务方权衡后仍倾向 uni-app x,以下六项应在开工前落实——它们会让这个选择的真实成本变得可见:
1. **F6 书面同意**在其页面中引入 `uni.webview.js`,并承诺配合联调排期。
2. **神策提供**与我方后端版本匹配的 uni-app x SDK,并明确后续支持与升级责任。
3. **Bugly 的 UTS 封装完成并验证**,含 iOS 侧的崩溃符号化。
4. **DCloud 明确 CLI / CI 的可行路径**;如果没有,我方需接受构建链路中存在人工用 HBuilderX 出包的环节,并据此调整发布流程。
5. **确认云端打包与离线打包的取舍**:是否会用加密付费插件,是否有需要离线打包的扩展需求,两者互斥时以哪个为准。**并明确知悉:即使走离线打包,原生工程仍是围着 DCloud 闭源二进制的壳工程,运行时行为不可改。**
6. **接受首版拿不到多端复用收益**——那六个小程序正在被这个项目关掉。
**前四项任何一项落不实,都应重新评估选型。**
### 6.7 最终结论
综合本项目的实际约束——架构路线的适配性、F6 集成、原生能力密度、指定的两个 SDK、既有的工程流水线、生态开放程度、以及五年周期内的能力天花板——
**我们推荐 Flutter。**
---
## 附录 A 数据与事实来源
本文档中所有关于 uni-app / uni-app x 的技术判断,**除单独标注者外,均来自 DCloud 官方文档或对应厂商官方文档**;社区数据取自 GitHub 公开接口。**非厂商官方来源全文共三处,均已在正文就地标注**:5.4 节的安卓小组件交付清单(社区实战教程)、4.3.1 表中百度贴吧一行(2019 年会议公开分享)、4.3.5 节的框架分布统计(第三方分析平台 Appfigures,已标为"丙档,只看趋势不下结论")。便于客户方自行复核。核验日期:**2026-08-25**。
| 结论 | 来源 |
| --- | --- |
| 主仓库 star / fork / 提交数等社区数据 | GitHub REST API[`flutter/flutter`](https://github.com/flutter/flutter)、[`dcloudio/uni-app`](https://github.com/dcloudio/uni-app) |
| 网页向 App 发消息需引入 `uni.webview.1.5.5.js`App 向网页走 `evalJS()` | [uni-app x — web-view 组件](https://doc.dcloud.net.cn/uni-app-x/component/web-view.html) |
| UTS 插件只支持通过 HBuilderX 创建和使用,不支持 CLI | [uni-app x — UTS 插件](https://doc.dcloud.net.cn/uni-app-x/plugin/uts-plugin.html) |
| 付费插件授权绑定 appid + 包名;加密 UTS 插件只支持云端打包 | [uni-app x — 插件发布与授权](https://doc.dcloud.net.cn/uni-app-x/plugin/publish.html) |
| iOS 小组件需 Xcode 做 `.appex` + UTS 插件携带 + `ios-extension.json` | [uni-app x — UTS 插件(iOS Extension 章节)](https://github.com/dcloudio/uni-app/blob/uni-app-x/docs/plugin/uts-plugin.md) |
| Siri 快捷指令仅靠 UTS 插件无法实现,需离线打包 + `AppShortcutsProvider` | [uni-app x — UTS for iOS](https://doc.dcloud.net.cn/uni-app-x/plugin/uts-for-ios.html) |
| 云端打包与离线打包的能力差异 | [uni-app x — 云打包](https://uniapp.dcloud.net.cn/uni-app-x/tutorial/app-package.html) |
| 离线 SDK 以编译好的 AAR 交付(`lib.5plus.base-release.aar``uniapp-v8-release.aar``utsplugin-release.aar` 等,不含源码);自定义 `Application` 须继承 `DCloudApplication`、默认 `MainActivity` 须移除;**「App离线SDK不支持Kotlin」** | [DCloud — App 离线打包(Android](https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html) |
| uni-app x 有独立的原生 SDK(分 Android / iOS / 鸿蒙版);**"仅支持VDOM模式,蒸汽(Vapor)模式的SDK还未发版"**;包体增量 iOS 约 8.7 MB、Android arm64-v8a 约 8.1 MB | [uni-app x — 原生 SDK / 渐进式集成](https://doc.dcloud.net.cn/uni-app-x/native/) |
| 云打包计费:每次 2 元;60MB 以下免费,超出按档加收 | [uni-app — 云端打包](https://uniapp.dcloud.net.cn/dev/app/cloud-build.html) |
| uni-app x 组件与 API 大部分 Apache-2.0 开源;Runtime / SDK 知识产权归 DCloud | [uni-app x 是什么](https://uniapp.dcloud.net.cn/uni-app-x/readme)、[uni-app 使用许可协议](https://uniapp.dcloud.net.cn/license.html) |
| uni-app x 不支持传统 uni-app 的原生插件;旧插件停止新增上架 | [uni-app x 是什么](https://uniapp.dcloud.net.cn/uni-app-x/readme) |
| nvue 基于修改过的 Weex 渲染引擎 | [uni-app — nvue 介绍](https://uniapp.dcloud.io/nvue-outline) |
| nvue 与 5+ 的官方维护于 2024 年停止,建议迁移 uni-app x | [uni-app x 是什么](https://uniapp.dcloud.net.cn/uni-app-x/readme) |
| Apache Weex 于 2021-05-14 从孵化器退役,仓库 2021-06-03 归档 | [Apache Incubator — Weex 状态页](https://incubator.apache.org/projects/weex.html)、[apache/incubator-weex](https://github.com/apache/incubator-weex) |
| 神策 uni-app x SDK 不在插件市场,需联系技术顾问索取 | [神策分析 — uni-app x 集成文档](https://manual.sensorsdata.cn/sa/docs/XD3SLh7B/v0300) |
| Flutter 官方 agent skills 与 MCP server | [Flutter — Agent skills](https://docs.flutter.dev/ai/agent-skills)、[Dart and Flutter MCP server](https://docs.flutter.dev/ai/mcp-server) |
| Flutter Skills 发布公告(2026-05-06 | [Introducing Skills for Dart and Flutter](https://flutter.dev/blog/introducing-skills-for-dart-and-flutter) |
| DCloud 官方的 uni-app x 与 Flutter 对比(包体 18M / 8.5M、内存约 138MB / 103MB、仅覆盖 VDOM 模式、"需求墙尚有未完成项"等自陈边界) | [uni-app x — 跨平台技术选型](https://doc.dcloud.net.cn/uni-app-x/select.html) |
| 字节跳动 90+ 款 Flutter 应用、800+ Flutter 开发者、产品清单与"节省约 1/3 开发时间"(口径为对比原生双端,出自字节 Flutter 基础设施团队负责人董岩) | [Flutter 中文站 — 字节跳动的多平台绽放秘诀 / 开发者故事](https://docs.flutter.cn/posts/flutter-bytedance-dev-story/)2026-06-22 更新) |
| 阿里巴巴 / 闲鱼、腾讯(调试效率 +80%、90% 代码多端复用、开发工作量 −33%)、贝壳找房的 Flutter 案例 | [Flutter Showcase](https://flutter.dev/showcase)、[阿里巴巴集团](https://flutter.dev/showcase/alibaba-group)、[腾讯](https://flutter.dev/showcase/tencent)、[贝壳找房](https://flutter.cn/showcase/beike)2021-03 |
| 美团外卖商家端 Flutter 覆盖 90% 以上业务、90% 以上成员具备 Flutter 能力(MTFlutter | [美团技术团队 — FlutterWeb 在美团外卖的实践](https://tech.meituan.com/2021/03/18/FlutterWeb-in-meituanwaimai.html)、[Flutter 专题页](https://tech.meituan.com/tags/flutter.html) |
| BMW:2018 年确认双端分叉、排除浏览器方案、2019-10 慕尼黑定案、2020-07 My BMW App 上线、覆盖 47 国五大洲、Mobile 2.0 Platform 每个构建自动产出并部署 96 个变体、截至 2021-10 每个变体累计构建超 10,000 个版本、Dr. Nicolai KraemerBMW 集团 Offboard Platform 副总裁)关于三根支柱的表述 | [Flutter Showcase — BMW](https://flutter.cn/showcase/bmw/)(英文原页:[flutter.dev/showcase/bmw](https://flutter.dev/showcase/bmw) |
| 大众汽车(安徽)ID. UNYX App 以 Flutter 承担「App 所有的 L1、L2、L3 页面」;同一站点另一份 SDK 说明中另列有 React Native SDK | [大众安徽 — 第三方个人信息共享清单](https://www.id.unyx.com/subp-YH20240626002)、[大众安徽 — 第三方 SDK 权限说明](https://www.id.unyx.com/subp-YH20240626003)、[App Store — ID. UNYX](https://apps.apple.com/cn/app/id-unyx/id6471565172) |
| 4.3.2 节配图 | BMW 两张为 My BMW App 官方宣传图;ID. UNYX 五张取自其 App Store 商店页官方截图。**配图只用于说明这两个 App 的功能面,不作为技术栈证据**——技术栈依据见上两行 |
| 携程主 App 为原生 + React Native + Flutter 混合,Flutter 用于火车票 / 酒店等核心业务列表页与主流程 | 携程技术《携程 APP Native/RN 内嵌 Flutter UI 混合开发实践和探索》(2021-10)、《Flutter 在携程复杂业务的高性能之旅》(2022-04),收录于[携程技术年度合辑](https://docs.c-ctrip.com/files/6/ctriptech/1gw291200099iy5uyCC5B.pdf) |
| 京东 JDFlutter2017 年起调研、物流 App 验证、技术中台建容器与工具链 | [京东 EMOP — JDFlutter 白皮书](https://opendoc.jd.com/base/emop/SPD/JDFlutter/1.white-paper.html)、[京东云开发者社区 — 京东技术中台 Flutter 实践之路](https://developer.jdcloud.com/article/1234) |
| 百度贴吧 Flutter 落地 **(2019 年会议公开分享,非官方文档,时效性已在正文标注)** | GMTC 全球大前端技术大会 2019 深圳站,百度高飞《Flutter 在百度贴吧的落地实践》 |
| 腾讯 Kuikly:基于 KMP、原生 UI 渲染、支持六端;内部 20+ 应用、1000+ 页面、5 亿+ 日活;产品清单;License 禁止为动态代码下发目的制作衍生作品;仓库建于 2025-04-24853 次提交 / 3,413 star / 300 fork | [Tencent-TDS/KuiklyUI(中文 README](https://github.com/Tencent-TDS/KuiklyUI/blob/main/README-zh_CN.md)、[LICENSE](https://github.com/Tencent-TDS/KuiklyUI/blob/main/LICENSE)、GitHub REST API |
| 安卓桌面小组件在 uni-app x 下的交付清单:3 个 Kotlin 文件 + Manifest 注册 + 3 个 XML 布局 + UTS 桥接;「每次修改这些文件后必须重新制作自定义基座」;需用 `getIdentifier()` 取资源 ID **(社区来源,非官方文档)** | 掘金社区 UTS 插件桌面小组件实战教程,2026-05-31 |
| 框架分布统计:2024 年 1–10 月新上架应用 Flutter 约 11.07% / RN 约 6.75%2022 年 10.15% / 4.73%);Top 10,000 非游戏 iOS 应用中 RN 1,350 个 / Flutter 1,184 个;Cordova 与 Ionic 下降 **(第三方分析平台,方法为扫描包内 SDK 特征,正文已标为丙档)** | [Appfigures — Non-Native Development Trends](https://appfigures.com/resources/insights/20241025)、[React Native's New Rival](https://appfigures.com/resources/insights/20251219) |
| Adobe PhoneGap 与 PhoneGap Build 于 2020-10-01 停服;Apache Cordova 仍在维护,2026 年仍有 `cordova-android@15.0.0``cordova-ios@8.1.0` 发版,`cordova-osx` / `cordova-windows` 已停止维护 | [Apache Cordova — Goodbye PhoneGap](https://cordova.apache.org/announcements/2020/08/14/goodbye-phonegap.html)、[Cordova Blog](https://cordova.apache.org/blog/)、[ASF 董事会纪要 — Cordova](https://whimsy.apache.org/board/minutes/Cordova.html) |
| Ionic Capacitor 1.0 发布于 2019-05-22,为 Cordova / PhoneGap 的现代替代 | [Ionic — Announcing Capacitor 1.0](https://ionic.io/blog/announcing-capacitor-1-0) |
| Google 明确不在 Flutter 主线支持鸿蒙(Closed as not planned);鸿蒙适配由 OpenHarmony-SIG 社区分支承接,2026-01 成立 Flutter SIG3.41 鸿蒙版已发布、3.44 鸿蒙版预计 2026-09 | [flutter/flutter issue #150536](https://github.com/flutter/flutter/issues/150536)、[OpenHarmony-SIG / flutter_flutter](https://gitcode.com/openharmony-sig/flutter_flutter) |
外部来源清单。凡本文档中标注为"推论"的内容(如"F6 需要改造页面"、"加密插件与离线打包互斥"),均由上表中的事实推出,推理过程已在正文中写明。
---
## 附录 B 术语表
给非技术读者:
| 术语 | 通俗解释 |
| --- | --- |
| **原生(Native** | 用 Android 和 iOS 各自官方的语言和工具开发,是"最正统"的做法 |
| **WebView** | 系统内置的浏览器组件。App 里嵌一个网页,就是靠它 |
| **JSBridge** | App 和它内嵌的网页之间的通话线路。网页想调手机的相机,得通过它 |
| **自绘引擎** | 不用系统自带的按钮和列表,自己从零画出每一个像素。Flutter 用的就是这个 |
| **Runtime(运行时)** | App 跑起来时在底下支撑它的那层引擎代码。它闭源,就意味着出了问题只能等厂商 |
| **UTS** | uni-app x 的编程语言,能编译成安卓的 Kotlin 和苹果的 Swift |
| **UVue** | uni-app x 的页面写法,基于 Vue |
| **nvue / 5+** | DCloud 上两代的 App 方案,官方维护已于 2024 年停止 |
| **Weex** | 阿里开源的跨端方案,nvue 的渲染引擎基础,已于 2021 年从 Apache 退役 |
| **Kuikly** | 腾讯 2025 年 4 月开源的跨端框架,用 Kotlin 写,渲染成系统原生控件 |
| **Cordova / Capacitor** | 最早的一批"网页套壳"方案,把一个网页包装成 App。Capacitor 是 Cordova 的现代继任者 |
| **KMPKotlin Multiplatform** | JetBrains 的方案,只把业务逻辑做成一份共用,界面仍要两端各写各的 |
| **Dart** | Flutter 的编程语言 |
| **Pigeon** | Flutter 官方工具。写一份接口定义,自动生成三种语言的对接代码,避免手写出错 |
| **HBuilderX** | DCloud 出品的开发工具(IDE),uni-app 系的插件开发目前离不开它 |
| **CLI(命令行)** | 不用打开图形界面,用命令直接执行。自动化流水线依赖这个 |
| **CI/CD(流水线)** | 代码提交后自动检查、自动构建、自动发布的机制 |
| **云端打包 / 离线打包** | 前者把构建交给厂商的服务器;后者在自己的电脑上构建,但拿到的工程核心仍是厂商编译好的二进制 |
| **AAR** | 安卓的二进制打包格式。拿到 AAR 只能调用它,看不到也改不了里面的代码 |
| **App Extension(扩展)** | App 主体之外的附加组件,比如桌面小组件、分享面板、语音助手指令 |
| **符号化** | 崩溃报告里原本是一串看不懂的地址,还原成"哪个文件哪一行出错"的过程 |
| **热更新** | 不经应用商店审核,直接把新版代码下发到用户手机上 |
| **VDOM / 蒸汽(Vapor)模式** | uni-app x 的两种渲染模式。后者更新,性能更好,但配套的原生 SDK 尚未发版 |
| **MCP** | 一种标准协议,让 AI 编程助手能读懂某个框架的专有知识 |
| **Agent Skills** | 打包好的一组指令,教 AI 编程助手按某个框架的最佳实践干活 |
术语对照表。
---
## 附录 C 对 DCloud 官方对比材料的核验
DCloud 官方文档里有一页专门做 uni-app x 与 Flutter 的对比(「跨平台技术选型」)。**客户方技术人员检索"uni-app x vs Flutter"时大概率会看到这一页,所以我们把它读完并逐条核验了。** 结果如下——凡属实的直接认,凡没有数据支撑的说明它没有数据支撑,不做反向解读。
| 对比页的论点 | 核验结果 | 对本项目的意义 |
| --- | --- | --- |
| Flutter 安装包更大(实测 **18M 对 8.5M** | **属实。** 自绘引擎必须打进包里,这是路线本身的代价 | 差约 10MB。门店内部业务 App,企业分发、无包体 KPI,不构成决策变量。且 uni-app x 走离线 / 嵌入路径同样有增量:iOS 约 8.7 MB、Android arm64-v8a 约 8.1 MBDCloud 官方数字) |
| Flutter 内存占用更高(实测 **约 138MB 对 103MB** | **属实** | 差约 35MB。门店配发的作业终端,现代机型上不产生可感知影响 |
| 「dart与原生API的通信…通信损耗非常明显」 | **未附实测数据与测试条件**,属定性表述 | 本项目的原生调用(扫码、拍照、上传)是低频、事件驱动的,不在渲染热路径;且接口由 Pigeon 生成三端强类型代码,不是字符串方法名。**本项目真正吃紧的通信链路是嵌 F6 那条——恰恰是 uni-app x 更弱的地方,见 3.1** |
| 「原生渲染和flutter自渲染并存时,问题很多」 | **未附实测数据**,但原生与自绘混排确是业界已知难点,这个方向上的提醒是成立的 | 本项目唯一的混排点是 WebView,用的是 Flutter 官方团队维护的一等公民插件,不是第三方封装。混排面积小且可控 |
| 「dart生态…以及比较难用的嵌套写法」 | 生态一项与第 4 章的公开数据相反(公开提交量、大厂落地规模均为 Flutter 占优);**嵌套写法这条是真实体验问题**,深层嵌套的可读性确实不如模板语法 | 嵌套写法属编码习惯与工具问题:IDE 的结构提示、格式化与重构快捷键已覆盖,团队上手一两周即适应。**这一条我们不辩解,但它不影响能力上限** |
| 「热更新」 | **属实,且是对方一条真优势** | 单独说明,见下 |
对 DCloud 官方对比页各项论点的核验。
> **这份对比里给出实测数字的只有包体和内存两项,差距分别约 10MB 和 35MB;其余论点均为定性表述,未附测试条件或数据。**
>
> 我们认为这个事实本身值得客户方注意:**一家厂商在自己撰写的公开对比材料里,通常会把手上最有力的证据放上来——而这份材料里最有力的证据是安装包大小。** 这从侧面说明了两条路线的差距集中在哪些维度上:不在能力,在体积。
**同一页里,DCloud 也标注了这份对比的边界。我们认为这些自陈是客观的,一并列出:**
- 该测试**仅覆盖 VDOM 模式**,蒸汽(Vapor)模式不在对比范围内
- 官方原文提到其**「需求墙尚有未完成项」**
- Android 侧页面元素过多时仍会拖慢性能,复杂场景需改用 draw 方式实现
- 引入常用库之后,uni-app x 的包体同样会增长
**这几条说明上面那两个数字是有前提的**:它们是特定模式、特定测试工程下的结果,不宜直接外推到一个有十几项原生能力、要嵌第三方网页的真实业务 App 上。
### 补充一条对方的真实优势:热更新
**uni-app 支持热更新(wgt 方式),Flutter 不支持。这一条我们主动列出,不等对方提。**
对很多项目来说这是实打实的价值——线上出了问题不用等应用商店审核,直接下发修复。需要一并说明的是:
- 苹果的审核政策对"绕过商店下发可执行逻辑"长期处于灰色地带,规模化使用存在被下架的风险敞口
- 本项目的发版链路已经定了:**安卓走托管的 OTA 分发页,iOS 走 TestFlight + App Store**,都是正规链路
- 企业侧的安全与合规评审,通常也不倾向于接受"可以绕开商店直接下发代码"这种能力
**所以准确的说法是:这条优势客观存在,但在本项目已确定的发版模式下用不上。** 如果将来发版策略改变、热更新变成硬需求,这一条应当重新计入。
### 这一节的用途
写这一节不是为了驳倒谁,是为了让评审会上不出现"我在网上看到 DCloud 说 Flutter 怎样怎样"这种悬空的讨论。**对方的每一条论点,上面都有一个明确的答复:属实的认下来并说明影响,没有数据的指出它没有数据,对我们不利的(包体、内存、热更新、鸿蒙)主动列出。**
结论不因此改变——**这些差异全部落在本项目不敏感的维度上,而第 3 章那几条落在敏感维度上的差异,方向是相反的。**