多团队合作开发微信小程序代码工程设计

63 阅读5分钟

背景

业务线多的时候,不管是一开始顶层设计就考虑多个技术团队维护同一个微信小程序,还是已经有了多个微信小程序要考虑合并,技术管理者都可能要考虑到:多个团队的开发如何更好维护一个小程序的问题

困难点

既然是多个团队,也就是开发之间物理距离比较远,不熟悉,要维护一个小程序,那就有可能带来管理、合作成本,包括:协调上线版本、公共方法/组件的维护、代码变动的确认等。

直接共用一个工程,在对代码规范强治理的公司,是难以接受的。而且开发、测试、运维的同事都有意见(关键是出事了责任主体可能不明确)。还是得拆分,多个工程各自独立维护为好。

这里把小程序的入口、门户、提供公共能力的我们这里叫做主工程,二级页面业务叫做子工程,分属不同的git工程。

主工程本地开发还好,入口、门户没有依赖,可以本地开发、预览。如果是子工程,没有权限接触到主工程,本地开发如何进行,那如何拉到稳定的主工程的代码?

如果一个版本有多个工程有协同的,比如 子工程和主工程一起改、子工程和子工程一起改,那如何开发、并提供稳定的测试版?

子工程如何复用主工程提供的组件、方法、变量?

设计取舍

在多团队之前,还有一个多端的小程序开发方式,uni-app 或 taro,这是一个吸引人的方向。微信、抖音、支付宝、小红书、web,同一份代码,一次改动,多端生效。

我们的情况是,已经存在了多个微信小程序,技术栈多是原生,也有部分 uni-app ,希望合并。查阅资料后,发现taro 可以混合开发,就是原生写法和 react/vue 可以一起写(docs.taro.zone/docs/taro-i… ,或者把原生直接转taro 代码(docs.taro.zone/docs/taroiz… 。uni-app 是建议基于vue的重构才行。

就我们这里实际的PV来看,微信占98成的流量。其他的平台的流量相对多端带来的代码、差异化成本,投入以及维护划不来。基于此,决定舍去在多端的投入(没了一个在PPT上可以画的饼),仅关注微信小程序即可。但如果能微信小程序和H5一套代码,H5 在自有APP上打开,似乎还有些优势。考虑运营差异以及不同API的使用,多端的成本还是认为偏高。不如就仅仅关注微信小程序。

这个定位下 taro 就显的重了。如果有一个仅仅能构建微信小程序原生代码的框架(有构建才能主、子工程复用)就最合适了。

构建的考虑

基于本人 vue 多年的开发经验(不清楚构建工具的细节)认为,构建微信小程序原生的入口是 app.json, 找到其中的 pages 列表作为入口文件,监控对应的 文件(.js,.wxss,.wxml,.json),使用 AST 代码分析等方式构建出符合 原生微信小程序的代码。理论上可行,同时监控如此多的文件可能会有性能不同。

实践

真的要自己写之前,还是要搜一下网络,是否有前辈有类似的方案?就找到了 Weapp‑vite(vite.icebreaker.top/) 这个基于 vite 构建微信小程序的框架。有了 vite.config.js ,就可以做 文件的移动(可以将子工程的代码copy到主工程来构建)、构建 alias 的定义(可以在主、子工程保障引用同样的组件)。

针对主工程的本地开发,以 weapp-vite 为主就好,参考结构:

- scripts
- - copySubModulesToMain.js
- - buildOnCI.js
- src
- config.json
- package.json
- vite.confg.js
- ...

其中 congfig.json 为子工程的配置文件,目标是在 CI 构建完整小程序的时候知道拉哪些子工程的哪些分支用来构建。

{
    subProjects: [
        {
            name: "保险",
            gitlabUrl:"xxxx",
            branch: "xxx"
        }
    ]
}

package.jsonscript

{
"script" :{
        "dev": "weapp-vite dev",
        "build": "weapp-vite build"
    }
}

针对子工程的本地开发,考虑到把主工程引入到项目中可以 结构为:

- main
- src
- - pages
- - ...
- .gitignore
- config.json
- package.json
- ...

其中,main为主工程代码,需要将 main 加入到 .gitignore 里。 config.json 的参考结构如下:

{
    subModules: {
        root: 'submodule-a',
        pages: [
            'pages/index/index'
        ]
    }
}

本地构建脚本,直接调用 main 主工程的里边的构建命令即可,调用子目录里的 script 可以用 --prefix ,如 npm run --prefix ./main build

要引入、更新 main 工程,这里还需要写个新的脚本来做。假设叫 weapp-cli ,提供如下功能

- weapp-cli create submodule // 创建子工程
- weapp-cli update --vertion=dev // 更新子工程中的主工程为dev分支的

创建和更新的脚本这里不展开了。

上面的 main 工程还有两个脚本

- scripts
- - copySubModulesToMainAndWatch.js // 监听子工程变动并拷贝到主工程里
- - buildOnCI.js // 流水线构建命令

说下 监听子工程变动并拷贝到主工程里 的逻辑,在 vite 构建的 开始构建之前的hook 节点,按照子模块的 config.json 的配置,整体 src 重命名(根据config.json的 root 配置)移动到 主工程下面,并对文件变化做持续监听。

流水线构建命令,就是在流水线上要把所有的工程拉取合并在一起,逻辑是:如果子工程出发的构建,则先拉取主工程代码,跑主工程的构建命令的过程中,根据主工程的 config.json 拉取所有子工程的代码,最终合并成一套完整的小程序代码。这里如果要多个工程合作协同开发的情况,需要在流水线上指定参数。

如有实现上的问题,可以留言再回复。

Q & A

  1. 还遗留的问题有哪些
  • 协同上线问题。因为共同开发一个小程序,那就需要各个组有个共同的协商机制,相近的版本要合并,当天只能有一个上线,不然分支可能会乱。