疾风知草劲,路遥知马力。在阿里,恐怕没有几个前端研发工具像 iceworks 一样,历史悠久,历久弥新。iceworks 第一版本发布于 2018 年 3 月,至今已经走过了近两个年头。笔者于 2019 年 4 月和 @思忠 开始接手,借本文分享笔者在这个领域的一些经历和思考。
时间点:2018.3 ~ 2019.4
iceworks 最初的定位是基于物料的 GUI 工具,产品形态是桌面客户端。这里面的出发点是通过该客户端,能够屏蔽前端工程环境和工程技术的复杂度,降低前端的研发门槛,让开发者能够快速地上手前端项目的开发。
为达到这样的目标,iceworks 2.0 有两个基本思路:一个是通过物料提升研发效率,第二个是通过 GUI 简化工程链路的使用成本。围绕着这两点,iceworks 2.0 形成了从通过模板初始化项目,到用区块搭建页面,再到通过可视化方式调试和构建项目、进行代码版本管理(Git),最后发布前端静态资源到 CDN 的开发工作流。
下图囊括了 2.0 主要的功能点:
在产品的组织中,因为是「基于物料」,所以物料占据了最大的比重;因为要「简化工程使用成本」,所以工程操作放在了最显著的位置,并且内置了 npm 和 Node。
这样的思路是否有效?还需要有数据的去分析做得怎么样。
但在这一方面,作为开发者,我们并没有足够的做产品的经验:iceworks 2.0 的数据采集只停留在了 DAU 和一些零散的操作次数的计数上。掌握的数据不足以进行有效的产品分析。而作为桌面客户端没有主动(强制)升级机制,所以版本的分布原因造成在补充数据采集后还需要一段时间进行数据积累。在这个阶段,我们能够知道只有:
这就是产品的现状。
技术上,为实现跨平台的桌面客户端,选择了使用基于 Electron 的架构:渲染进程中加载的是一个 ICE 1.0 构建的前端应用;主进程则是一个“自研”的 Node 应用,负责操作项目文件和执行 npm 命令。两者通过 Electron 提供的 IPC 进行通信,渲染进程通过 remote 使用主进程模块。下图是 2.0 的技术架构:
前端应用里面有几个比较大的模块:
Node 应用里面划分了以下几个模块:
这就是技术的现状。
产品上,从数据和用户的反馈来看,在日常开发中用户对 iceworks 的依赖非常弱,通常只是用来初始化项目和启动调试,使用频率很低 —— 那么这个工具就成了一个食之无味弃之可惜的东西;为寻求突破,我们做了很多 PoC,频繁迭代过程中丢失了产品体验:监控后台每天堆积如山的 undefined 错误日志反映了产品稳定性不足,我们也投入了大量精力去进行用户答疑。
技术上,架构设计的不合理问题在迭代过程中开始暴露,从上面的架构图中可以看出:模块分层职责不清,模块间调用关系混乱;而功能烂尾和为赶功能而产生了产生了大量冗余和临时 Hack 代码,这些都成了技术的负债;另外一些需要投入大量精力建设的能力缺失,如持续集成能力、有效监控和日志的收集等。这些问题直接导致:
这仿佛是马太效应,每况愈下。
在人员能力上,团队对如 npm 执行原理、node-pty 实现原理、electron-builder 还不能做到自主可控,遇到问题全靠查漏补缺。
时间点:2019.4 ~ 2019.10
为结束产品混乱的状态,还清技术债务以及建设团队人员能力,大概是在 19 年 4 月左右,我们启动了 iceworks 3.0 版本的开发。目标是让产品更简单和友好,技术更稳定、更可维护和可扩展。
为了让产品做到更简单和友好,我们对产品的组织结构进行了梳理,把工作台划分为项目开发、工程链路、物料管理和个性化设置四大部分。同时在项目开发中,有明确的价值引导。这背后的思考是:
红色部分为新增功能,中划线部分为删减功能。
相对于 iceworks 2.0 来说,iceworks 3.0 做了一些加法,目的是为了 「更好用」,这些加法有:
相应的,也做了一些减法,目的是为了提高投入产出比:
在技术上,新架构基于 Web。这样的架构模式在一些成熟的桌面客户端中均有实现,例如 VsCode 和 Theia。基于 Web 的架构可以在命令行工具、桌面客户端和在线版本间更好地进行适配,下图是 3.0 的技术架构:
对于 iceworks 这样的产品形态来说,它的前端应用架构复杂度不应过高。主要要解决的问题是如何组织视图的模块结构、如何做状态管理、如何与服务端进行双向通信。在此过程中,我们沉淀出了 icestore 这样的轻量级状态管理方案。
在服务端,使用 midway 做了一个轻量级的 Node 应用,只有三个路由:项目操作相关的、物料管理相关的、个性化设置相关的。服务端承担的职责是对项目本地文件的操作和执行 Shell 命令。
在服务端,对 GUI2Code 对应的操作都可以模块化,例如是操作路由、菜单还是页面?这些子模块的 API 是固定的,只是背后的实现有所差别。因此,我们抽象了 Adapter 这一层,总结可操作的模块有哪些,操作的内容有哪些,标准化接口,实现基础操作包,完成对 ICE 官方项目的支持。如果需要支持其他类型的项目(CRA/Vue),则可以继承基础包进行扩展,又或者只遵循标准接口实现自己的操作包即可。通过这样一套模式,即可做到对 ICE 不同版本项目的兼容,又可以扩展支持其他类型的前端项目,提升了应用架构的扩展性。
关于 icework 3.0 版本的 Adapter 模式后续会有详细的文章介绍,这里不再展开。
有了合理的分层,再去做数据采集、日志监控或单元测试就方便多了。
吸取了 2.0 版本在数据采集上的疏忽,在 3.0 中,我在 socket 的分发层收集所有用户的操作,这样便把数据细分统计到用户在哪个域下(项目/工程/物料/设置)的哪个模块(Git/Menu/Page)执行了什么动作(create/delete/update)。这样便可以比较完整地统计到所有的功能使用情况,利于未来进行产品分析。
在日志监控上,前端使用封装的 Logger 工具库打日志, Eslint 禁止在代码内使用 console,Logger 中使用 ARMS 进行前端监控和收集错误日志;服务端借助 egg-logger 的 transport 能力,在生产环境中将指定 level 的日志收集到 SLS,对日志持续进行分析和监控。
可以从以下几个维度去看产品:
得益于 Adapter 层,新版本的所有功能对 ICE 新老项目都达到了 100% 的支持……
在技术上的收获则更大:
沉重的技术负债在这一版本中终于得到了解脱。
时间点:2019.10 ~
在 icework 3.0 功能稳定后,摆在我们面前有几个问题:
对于第一个问题,一个简单粗暴的方式就是将 3.0 版本包一层 Electron 的壳,这就成了新的桌面客户端版本,然后让用户升级上来。但是以现有提供的辅助性功能来说,没有提供一个桌面客户端的必要。市面上桌面客户端形态的开发工具主要有两种,一种是专注于解决单点问题的软件,例如 iHosts、Beyond Compare、Sourcetree 等;另一种则是 IDE,如 Atom、Xcode、WebStorm 等。3.0 可视化辅助工具的特性做成桌面客户端没有明显的收益点。
对于第二个问题:
对于第三个问题,淘系中后台业务研发将会升级到小二工作台产研平台中完成,产研平台将在线上完成研发流程的流转。这就更需要我们在云端研发模式上有所作为。
因此,我们将基于编辑器去做全新的研发工具,这就是 iceworks IDE 的想法:
红色部分为新增功能,中划线部分为删减功能。
在我们的计划中,iceworks 将会覆盖先前版本中的大部分功能,同时,重点建设以下能力:
相关功能将逐步以 PoC 的方式进行,持续探索和定义符合企业级产品的 IDE。
在 iceworks 4.0 的技术架构中,IDE 底层技术基于阿里集团 IDE Framework,我们封装本地 IDE 的集成能力,沿用 iceworks 3.0 中适配层的能力封装出 IDE 插件,构建出本地的桌面客户端。下图是 4.0 的技术架构:
关于 iceworks 4.0 的技术架构未来会有详细的文章进行介绍,这里不再展开。
罗马不是一天建成的。iceworks IDE 目前仍处于内部孵化阶段,在淘系小二工作台场景中落地。以业务作为技术的试金石和土壤,逐渐沉淀出适合企业级产品的研发模式和开发工具。对外的版本,我们将在 12 月中下旬释放。
在初期,我们会更关注开发者对新 IDE 的接受程度,核心关注留存率指标。面向长期,我们会重点关注 IDE 对研发体验和研发效率的提升度,具体的衡量指标还在制定中。
做出改变、思考创新是风险很大的事情。但如果墨守成规,则很难有新的眼光和方法去突破现有体系的瓶颈。我们始终在大胆设想,小心论证。
iceworks 作为 ice 下的开源项目,所有的编码和讨论均可通过 Github 仓库回溯:
iceworks 4.0 版本也将会在未来合适的时机开源,欢迎关注、讨论。
← 当 SSR 遇上 Serverless,轻松实现页面瞬开 Rax PWA - 快速升级 Web 体验 →封面图来自《沙巴的夕阳》。