笔者的感概: 从现在的趋势看,App 开发者未来究竟会是终端工程师,而终端工程师要会的技能除了要了解各端开发完成外,更重要的是具备串联各端、各言语的能力。
引言
去年写了篇文章,讲了下笔者了解的跨端东西链是什么样的。
在补齐跨端通讯能力(GNB)后,整套东西链在稿定终端开发中已经是一个成熟体系了,能够体系的来介绍下咱们在其间是做了些什么,是怎样落地的。
相关文章
《说到跨端东西链,咱们是在说什么?》
《跨端通讯终结者|看我是怎么确保多端消息一致性的》
能力概览
跨端东西链是一个抽象概念,意图是把端与端的联系经过东西链条联系起来。
在具体完成上,咱们是落在终端服务层(application-services),从物理架构上看,它便是一个独立的 git 库房。
包含生成服务、终端组件、开发辅佐扩展三个部分。
那咱们怎么来了解终端服务层?
咱们结合 DevOps 的概念来看,终端服务其实是在 Dev 前置一步的环节中,为了开发服务的一层,往往是在构建前或许构建进程中参与编译运用。
生成服务
生成服务(codegen)类似工厂车间,它能够依照标准输入,依靠固定模板,生成标准输出的各终端产品。
想了解具体生成进程的,能够看这篇文章:从零开始|构建 Flutter 多引擎渲染组件:跨端东西链篇
东西言语选型上,前期多运用 Ruby 言语,原因是为了开发运用方便,究竟公司内部都是用 Mac 开发,MacOS 内置了 Ruby 环境,没有什么预装置本钱,合适前期探索落地。后续,考虑到与打包机、Dock 容器等环境保持一致,所以逐步迁移成 Python 来开发。
无论是什么言语开发,都会添加 shell 文件main.sh
来确保运用进口的一致性。Flutter 组件化东西以及跨端通讯协议还会添加preview.sh
来生成 markdown 预览文档。
在标准输入上,也会根据实际需求有一些差异,由于数据来历是不一致的,有些服务需求读取服务端接口,有些自闭环的能够写在生成服务本身,还有一些能够写在各个项目中,经过必定标准即可让东西读取到。
那在产品输出上也有差异,有些是作为文件直接生成到项意图模块中,功能上相对独立的会生成产品 SDK,作为终端组件。
终端组件
但凡能够打包成 SDK 的,究竟会被打包成 SDK。
咱们在前期东西链规划上,产品尽量是一个独立的终端组件,以轻量为主。意图便是在后续稳定时能够提供独立的 cocoapods / gradle / npm / pub / … 组件库,乃至是提供二进制库的方法来削减构建本钱。
在组件人物上,现在是划分的比较清晰:调用组件/支撑组件。望文生义,比如 GNB 消息通讯能力在 iOS / Android / 桌面端是支撑组件完成,而 Web / Flutter 是调用组件完成。
但这也不是肯定的,比如后续 Rust 加入进来,那 Rust 侧便是支撑组件的方法,而其他代码侧则是构建调用组件。也比如或许也会让 Flutter 来支撑 Web 开发。
在运用上,只需项目集成就能够具备相应的跨端能力,抹平各个渠道差异性。
组件 SDK 化的另一个优点是调用 API 是不变的,对于上层事务来说不关心是怎么完成的,SDK 怎么变化,也无需改变事务代码,更改生成模版代码即可。
开发辅佐扩展
可自动化的究竟会自动化,可 AI 完成的究竟会让咱们赋闲[狗头]。
什么是开发辅佐扩展? 提高开发效率,下降人为因素导致的意外问题的东西。咱们更想把它了解成稿定终端 IDE的前身,现在是在VS Code上初步建设了Web & App Flutter & App 两个开发辅佐扩展,用于把整个跨端开发构建流程自动化起来,削减开发同学心智本钱,让开发只关心一端代码即可。
后续演变上,IDE建设便是把项目、运转终端设备、开发辅佐扩展三者结合起来,让 Web / Flutter 工程直接在 App 项目中上构建运转调试。
开发参考:构建 VS Code Extension,提高 Flutter 开发效率(一)
落地方法
前面是介绍咱们在稿定终端开发中跨端东西链都做了什么,也用终端服务层(application-services) 的方法把它们结合在一起。
但其实有一个非常重要问题,怎么把终端服务层(application-services) 落地到具体的各个项目中,这问题的实质是在多个库房代码怎么有机的结合在一起。
这个问题也有许多种解法,笔者逐个列出,然后讲一下咱们的最佳实践。
计划选型
二方库/三方库
构建完成后组件上传到内部库房(二方库)或许上传到 github / npmjs / pub / ..(三方库),当作独立组件来运用。
按理说这算是终究形状,但假如改动频频就涉及到发包的问题、事务项目也要频频的修正包版别号,对小范围内部开发来讲不友好。并且每个组件都需求独立一个版别号,版别号办理起来本钱也非常大,比如发包前就要查看各个组件的版别清单。
Git 子模块(submodule)
Git 对于复杂多项目也提供了一个解决计划,运用 submodule 子模块的方法,把组件作为一个独立的库房加入到事务库房中。
看起来很契合咱们的需求,但它的问题是自身存在许多缺点,这儿不搬运其他文章过来了,有兴趣的能够在搜一下 git submodule 的坑。
咱们的最佳实践
最后咱们运用的这个方法姑且称作脚本库房办理,市面上的确没有人说有这么做,但作用的确意外的好。
到底是个什么样的计划?
一句话描绘:各终端库房经过添加脚本代码setup_application_services.sh,自行经过各个言语环境的东西链,集成到项目构建进程中。
setup_application_services.sh
# 链接应用服务
#!/bin/sh
VERSION=0.1.1 # 运用的版别号,后续解说作用
CURPATH=$(
cd "$(dirname "$0")"
pwd
)
cd $CURPATH
DIRECTORY=../application-services # as 服务下载位置,建议放到项目根目录
if [ ! -d "$DIRECTORY" ]; then
git clone git@git.gaoding.com:gdmobile/application-services.git $DIRECTORY
fi
cd $DIRECTORY
git clean -f
git reset --hard
git remote update origin
git checkout $VERSION
git pull origin $VERSION
cd ..
具体讲一下这个脚本的作用:
- 直接把application-services库房下载到工程内部,作为一个完整的子文件夹。
- 清理掉或许被开发操作的库房改动。
- 拉取该分支下最新的代码。
这样来确保每次履行脚本,都能够取得一个契合版别预期的正确库房内容。
VESION
常量实质上是指定git branch
分支号,只不过咱们生成名称为版别号的分支来完成的更高雅。(在开发测验中,笔者都是新增开发分支VERSION=dev/xxxx
来做)
这种方法带来的优点:
- 版别号能够统一办理。
- 确保开发环境的干净,每次履行脚本都会还原一些意外的误改动。
- 可当作普通组件修正测验,只需不履行脚本,就能够直接修正其间代码来验证问题。
仅有的害处是拉取的是整个库房,跟工程无关的代码也会被拉取下来,但这是可接受的,对于开发而言只是硬盘多占用一些,在开发进程中不受影响。
各端落地方法
稿定在各端项目上都是采用 Monorepo 多项目大仓办理的模式,所以咱们需求的也是把application-services中的组件也当作它的一个项目,这样来抹平开发的认知本钱。
也不能让开发同学手动去调用脚本,这样也太不高雅了,咱们还需求把它融入到整个集成流程中。
下面分开讲下不同的工程咱们都是怎么做的(划重点)。
iOS
iOS 需求在 Pod 之前提早履行application-services.sh。
首先需求在Podfile
中最前面添加模块引入。
这样让 Pod 履行前先去履行manager.rb
文件。
manager.rb 中要害代码:
# 拉取最新的 application-services
def setup_application_services
Pod::UI.puts "check git application-services".green
system File.join($PROJECT_PATH, "tools", "setup_application_services.sh")
end
在履行pod install / pod update
时,就会先去履行setup_application_services.sh
脚本。
然后是怎么运用大仓模式呢?
这儿推荐大家两个 Ruby 插件:cocoapods-monorepo 、cocoapods-headermap,用于大仓办理的,这都开源在 RubyGems(前同事留下的成果 ~)。
这儿添加application-services下载后的文件夹索引路径即可。
但开源版别只支撑传单个 path,需求进行一些扩展改造,建议下载插件源码到本地来运用。
Android
Android 比较简单些,只需新增一个 Gradle 履行文件即可。
application_services.gradle
task Setup(type: Exec) {
exec {
commandLine rootDir.getParentFile().getParent() + '/tools/setup_application_services.sh'
}
}
而 Monorepo 公司 Android 是采用的手动指定,但也完全能够经过一个 Gradle 来遍历查询。
Flutter
Flutter 比较费事一点,由于flutter pub get
流程并不合适做钩子,所以咱们采用了另一种方法,利用 VS Code ExtensionFlutter 开发辅佐东西添加指令来帮助开发把这个流程自动化。
Monorepo 也是经过手动指定依靠路径。
Web
Web 脚手架比较完善,很容易集成进去。
scripts 添加一下调用即可。
而 Monorepo 前端就更成熟了,咱们运用 pnpm 的大仓计划即可。
pnpm-workspace.yaml
packages:
- "src/*"
- "../application_services/*"
总结
当时的跨端东西链建设只是开始,当下在稿定内部也逐步推广起来,慢慢分散到各个团队中去运用,未来上还是有更多的或许性。
感谢阅读,假如对你有用请点个赞 ❤️