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-web,packages/ui/vue-components,这两个目录下,只要存在package.json 文件,就会被pnpm 认定是一个包

下面的catalogs.vue3 这个是版本变量声明,可以把它当做是一个依赖的变量,在 a-web/和 b-web 的 package.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-web 的 package.json可以这么写:

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

或者也可以用命令加入:

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

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

怎么针对某个子包执行 dev 命令,注意这个包的package.json.name为 a-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的层缓存机制。

持续更新中。

相关推荐
IMPYLH23 分钟前
HTML 的 <wbr> 元素
前端·html
Dovis(誓平步青云)44 分钟前
常用命令藏得太深?怎么做一个快捷命令坞
运维·前端·自动化·音视频·prometheus
IT_陈寒2 小时前
Vite的这个问题坑了我三天,原来如此解决!
前端·人工智能·后端
网易云信2 小时前
大模型能上岗做销售吗?我们让 12 款国产模型交了 420 份作业
前端·后端
蜗牛互联网2 小时前
Python Agent工具调用的白名单、参数校验与审批门禁
java·服务器·前端·人工智能·后端·python
计算机魔术师2 小时前
Perplexity:每个 Project 都是一个 Git 仓库
前端
Andrew5512 小时前
让 AI 写页面不再“一眼假”:我把设计品味做成了一个 Claude Code Skill 流水线
前端
乐享qicheng2 小时前
14-AI智能管家JSBridge深度问答
前端
10年前端老司机3 小时前
我用 Vue3 + LangGraph 做了个心理咨询 AI,踩了 9 个坑后总结出来的实战经验
前端·langchain·agent
数据掘金3 小时前
A/B 实验分组参数回滚后还在生效?一次参数校验体系的重构复盘
前端