基于 pnpm 的云函数本地 monorepo 项目管理

1,171 阅读4分钟





一、前情提要

1.1 业务背景思考

如果有了解和接触过微信小程序的云函数开发,大家应该都知道万恶的TX的设定下,一个云函数虽然看起来更像对应的一个 request 而已,但是从项目管理、项目依赖这层角度来看,一个云函数宛如就是一个简单的 npm 项目,一开始项目微型这种管理形式并不存在多大问题,但是随着项目迭代,越来越多的云函数怼了上去,这时候各个云函数之间存在自己的依赖,这些依赖大部分都是相同的,但是不去优化,在本地进行调试就相当于是一个灾难性的资源消耗(安装所消耗的时间、所消耗的体积空间),因此日积月累也在思索有没有能够优化的途径。

同一代码仓库但是存在多项目?那不就是直接就是将“monorepo”这个关键字直接写在脸上了吗?好的,得到一个项目管理优化的大方向了,因此我这个面向搜索引擎搬砖师立马进行了相关知识的搜索。

1.2 技术选型

什么是 monorepo ?

最直白的理解方式monorepo就是在一个仓库代码当中存在着多个子项目。这里牵涉到另一个知识multirepo,multirepo 项目管理方式的缺点主要能划分为三个:

  • 多个项目间的代码的复用复杂;
  • 项目依赖的版本管理繁琐;
  • 项目部署等基建资源的重复浪费及维护成本;

monorepo可以说就是为了解决 multirepo 的这些痛点而存在的。关于 monorepo 的更多的概念可以参考神三元大佬的一篇文章:现代前端工程为什么越来越离不开 Monorepo?

实现 monorepo 的方式

方案备选

  1. yarn workspace
  2. pnpm
  3. Lerna

敲定落实

反观当前的业务场景:微信小程序的云函数真实部署受限(微信限制只能一个独立的云函数一个 package 项目并且限制只能特定形式部署上传,因此其实我们无权管理云函数的真实生产项目部署管理),仅能在本地开发时候各种花式去玩(嗨,无奈啊)。鉴于上述我们这里的应用场景其实也是非常简单的:如何优雅的统一管理多个 npm 子项目的依赖。

因此最终选型选择的是简单易上手的仿佛专为 monorepo 项目而生的pnpm的技术方案。





二、技术实践

其实主要还是利用 pnpm 的 workspace 技术来实现多个 npm 子项目当中统一进行依赖管理。

2.1 实际技术改造落地

  1. 首先在一个云函数的统一的目录当中新增pnpm-workspace.yaml文件,并且填写子 npm 项目的匹配规则。

    • 规则主要是设置当前 pnpm 的根目录(这个目录会存放真正的依赖包的文件,npm子项目内的 node_module 内的依赖包都是通过软链接形式连接这目录下的node_module/.pnpm目录的真实依赖代码文件;
    • 另外还需要设置包含或者需要排除的 npm 子项目的路径(参考形式如下);
# pnpm-workspace.yaml

packages:
    # root directory
    - "."
    # all packages in subdirs of packages/
    - "./functions/**"
    # exclude packages that are inside test/ directories
    - "!**/test/**" # '!' means exclude
  1. 接着在pnpm-workspace.yaml的文件目录下运行pnpm install指令。

此时等待pnpm进行子项目管理的匹配和对应项目依赖的安装。命令执行完成后,能够在pnpm-workspace.yamlpackages 配置中匹配中的子项目目录中看到已经存在对应的node_modules项目依赖文件了。

  1. 重新打开微信开发者工具开启本地云函数调试也是没问题了





三、总结与思考

3.1 优化结果

优化前体积(60+ mb) --> 优化后体积(20+ mb)

可以看到我们使用pnpm + workspace后充分利用其优势(得益与pnpm的缓存与安装机制),安装速度加快并且项目总的依赖文件占用的体积和文件数量都大幅度减少。并且能够统一的在一个目录的一个指令就能够对本地的云函数进行一个依赖的安装与更新,着实方便多了。


3.2 其他的可能性

其实技术都是相通的,像老牌的 npm 与 yarn 其实都是能够解决掉当前这个小场景的 monorepo 项目,都只是一个触类旁通而已。

这里也仅仅是利用了技术的 api 实现了效果,但是其实没有深层次的进行一个技术底层的真正实现,后续也会深挖 pnpm 底层实现的这块。并且在这里受限于应用场景的微小,也仅仅是利用了技术的 api 实现了简单的 monorepo 项目管理的效果,很多高级特性像 monorepo 的项目部署、代码仓库管理等也需要后续推广落地实践到其他的项目当中。





参考资料