25 年上半年总结以及关于pnpm monorepo 的一些使用记录

背景

我上半年在工作上做的一些项目架构优化工作,包括:

  1. 微前端进行了 pnpm + monorepo 的改造,将主应用及多个子应用应用于此架构。
  2. 将组件库、请求库迁移进上述 monorepo 架构中,并且设计了cicd 流程,只要这些包发生更新,便使依赖这些包的前端服务重新编译部署,也是因为 monorepo,让关联的更新操作自动化,不像以前那样要逐个前端服务下手动 npm i $包名@latest 这般操作使来更新。
  3. 在请求库中使用了 openapi-ts-request 这个工具,自动生成请求函数,再也不用重复地手写请求函数了
  4. 组件库里集成了 Storybook 这个在线文档技术来做文档和 demo,不过只是跑通了,还没深入地使用,在组里面推广这项技术也碰到了阻力。

为什么要用 monorepo 架构?

因为部门的项目,前端用了微前端实现的,背景大概是这篇文章,而微前端里面的子应用,其实有很多可以复用的配置文件,包括像:

  1. Dockerfile、有规律地创建唯一的子应用目录,比如像 /a-web/ 、/b-web/;
  2. nginx 的配置、每一个前端服务的 nginx 配置里,都要写跨域配置;
  3. 子应用的通信交互逻辑,包括像子应用接收用户、权限数据,接收要跳转的路由数据

像上述的这些文件,每个子应用都有,而每个子应用又对应一个代码仓库,就比较零散不好管理,对新人也不友好。我认为更合理的做法是,主应用和子应用放在一起,配置集中管理,优化,上下文能更加清晰,开发也更加方便,因为开发也是要主,子应用一起启动的。

为什么要用 pnpm + monorepo 来改造?

因为很久以前就有看到过相关的文章,比方说babel库就是用了lerna 来进行管理,但是可能是本人比较愚笨,好几次尝试着用lerna 来建项目,始终有各种问题,跑不起来,最终还是搁置了。

但是今年发现pnpm竟原生支持monorepo 的特性,而且搭起来异常的简单,所以就上手用 pnpm 来将公司的分散的微前端应用集中起来了。

总结了一些常见用法(持续增加中)

一份pnpm monorepo配置如下:

yaml 复制代码
packages:
  - 'apps/*'
  - 'packages/**/*'

catalogs:
  vue3:
    vue: ^3.2.13
    vue-router: ^4.5.0
    vuex: ^4.1.0
    '@arco-design/web-vue': ^2.57.0

上面的 packages 字段声明了包的位置,比如apps/a-webpackages/ui/vue-components,这两个目录下,只要存在package.json 文件,就会被pnpm 认定是一个包

下面的catalogs.vue3 这个是版本变量声明,可以把它当做是一个依赖的变量,在 a-web/和 b-webpackage.json 里面,依赖可以这么写:

json 复制代码
"vue": "catalog:vue3",
"vue-router": "catalog:vue3",
"vuex": "catalog:vue3"

假设,apps/a-web 依赖packages/ui/vue-components,并且vue-component的包名(package.json.name) 是vue-components,那么在apps/a-webpackage.json可以这么写:

json 复制代码
"vue-components": "workspace:*",

或者也可以用命令加入:

bash 复制代码
pnpm add "vue-components@workspace:*" --filter a-web

注意,当包含@符号时,要用双引号包裹包名。

怎么针对某个子包执行 dev 命令,注意这个包的package.json.namea-web

bash 复制代码
pnpm --filter a-web dev

怎么对多个应用执行 dev 命令?

bash 复制代码
pnpm --filter a-web --filter b-web dev

列出当前的pnpm 所有包,可用于快速查看所有包名

bash 复制代码
pnpm list -r

解决了一些问题:

  • Docker 编译速度太慢

在 monorepo 架构下,假设场景为,a-web前端服务,依赖 services 请求库、vue-components 组件库,那么就会出现下面这种 Dockerfile 写法:

dockerfile 复制代码
...
COPY pnpm-workspace.yaml ./
COPY pnpm-lock.yaml ./
COPY package.json ./
COPY packages/services ./packages/services
# 假设依赖 请求库, vue-components 组件库
COPY packages/services ./packages/services
COPY packages/ui/vue-components ./packages/ui/vue-components
COPY apps/a-web ./apps/a-web
RUN pnpm install
...

这么写能用,但是有个问题,就是pnpm install 命令这个层,会随着这几个库或者前端服务的代码改变,而始终没办法缓存起来,导致每次编译,都要执行pnpm install,影响了编译的速度。 优化如下:

dockerfile 复制代码
...
RUN mkdir -p apps/a-web packages/services packages/ui/vue-components
COPY package.json ./
COPY pnpm-workspace.yaml ./
COPY pnpm-lock.yaml ./
COPY apps/ds-server-gateway2-web/package.json ./apps/ds-server-gateway2-web/package.json
COPY packages/services/package.json ./packages/services/package.json
COPY packages/ui/vue-components/package.json ./packages/ui/vue-components/package.json
RUN pnpm install --registry $私有仓库地址
COPY packages/services ./packages/services
COPY packages/ui/vue-components ./packages/ui/vue-components
COPY apps/a-web ./apps/a-web
...

也就是前置各个包的 package.json 拷贝操作,pnpm install 操作,来命中Docker的层缓存机制。

持续更新中。

相关推荐
二哈喇子!6 分钟前
Vue3生命周期
前端·javascript·vue.js
运维帮手大橙子4 小时前
完整的登陆学生管理系统(配置数据库)
java·前端·数据库·eclipse·intellij-idea
_Kayo_5 小时前
CSS BFC
前端·css
二哈喇子!6 小时前
Vue3 组合式API
前端·javascript·vue.js
二哈喇子!7 小时前
Vue 组件化开发
前端·javascript·vue.js
chxii8 小时前
2.9 插槽
前端·javascript·vue.js
姑苏洛言8 小时前
扫码点餐小程序产品需求分析与功能梳理
前端·javascript·后端
Freedom风间8 小时前
前端必学-完美组件封装原则
前端·javascript·设计模式
江城开朗的豌豆8 小时前
React表单控制秘籍:受控组件这样玩就对了!
前端·javascript·react.js
一枚前端小能手9 小时前
📋 代码片段管理大师 - 5个让你的代码复用率翻倍的管理技巧
前端·javascript