4 pnpm
约 1718 字大约 6 分钟
2025-06-18
维度 | 传统架构 | monorepo |
---|---|---|
依赖管理 | 每个项目单独管理依赖 | 统一管理依赖,减少版本冲突 |
公共模块复用 | 需要手动同步和发布 | 子包间直接引用,快速构建 |
构建效率 | 每个项目单独构建,耗时长 | 按需构建,提升效率 |
磁盘占用 | 重复安装,磁盘占用高 | 去重机制,节约磁盘空间 |
协作成本 | 跨项目协作复杂,测试联调耗时 | 单仓库集中管理,便于协作 |
- 传统架构
- 独立项目结构,所有项目都是分开的github仓库
- 技术栈独立
- 规范化、自动化相关处理是项目间割裂
- 依赖管理,版本很难统一管理
- 部署,docker、docker、compose,自动化脚本很难形成统一
- monorepo架构
- 混合项目结构,所有相关的工程形成子包进行管理
- 技术栈高度统一,(团队基建项目、业务项目、子服务,技术栈)
- 规范化、自动化、流程化项目间共享
- 依赖管理,版本统一管理
- 部署,docker、docker、compose,自动化脚本统一部署流程
monorepo
使用pnpm的workspace来管理monorpo项目
- 在主项目的根目录下根据不同的逻辑划分不同的工作区以便于管理 假设项目根目录为以下示例:
├── apps
│ ├── backend
│ └── frontend
├── node_modules
├── packages
│ ├── charts
│ ├── cli
│ ├── tools
│ └── ui
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml
- apps中存放项目逻辑,其中分为前端和后端的逻辑各分一个工作区
- packages中存放通用的工具等,根据职责的不同划分ui、tools、cli、charts工作区
- 在主项目的根目录中创建
pnpm-workspace.yaml
文件,并定义查找各个分包的规则
packages:
- 'packages/*' //查找项目根目录下的packages文件夹中的所有工作区
- 'apps/frontend/*' //查找项目根目录下的apps文件夹中的frontend中的所有工作区
- 'apps/backend/*'
- 不同工作区之间相互依赖 对于项目中不同工作区的依赖引用,monorepo使用的是链接机制:当前工作区若依赖了本地其他工作区的内容,需要在package.json中配置引用和引用路径,如:
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"@miaoma/ui": "workspace:*", //本地工作区依赖
"@miaoma/cli": "workspace:*" //本地工作区依赖
},
workspace:*
表示在主项目的所有目录中搜索该包,也可以手动指定路径 之后使用pnpm i
命令安装依赖时会在node_models文件夹中创建该报名的文件夹并将链接指向找到的包位置,不会多余的安装
微前端
微前端是借鉴了微服务的理念,将一个庞大的应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发,独立运行,独立部署,还可以随意组合,这样就降低了耦合度,从而更加灵活。
iframe 通过iframe实现就是每个子应用通过iframe标签来嵌入到父应用中,iframe具有天然的隔离属性,各个子应用之间以及子应用和父应用之间都可以做到互不影响。
但是iframe也有很多缺点:
- url不同步,如果刷新页面,iframe中的页面的路由会丢失。
- 全局上下文完全隔离,内存变量不共享。
- Ui不同步,比如iframe中的页面如果有带遮罩层的弹窗组件,则遮罩就不能覆盖整个浏览器,只能在iframe中生效。
- 慢。每次子应用进入都是一次浏览器上下文重建、资源重新加载的过程。
single-spa single-spa是最早的微前端框架,可以兼容很多技术栈。 single-Spa首先在基座中注册所有子应用的路由,当URL改变时就会去进行匹配,匹配到哪个子应用就会去加载对应的那个子应用。 相对于iframe的实现方案,single-spa中基座和各个子应用之间共享着一个全局上下文,并且不存在URL不同步和UI不同步的情况,但是single-spa也有以下的缺点:
- 没有实现js隔离和css隔离
- 需要修改大量的配置,包括基座和子应用的,不能开箱即用
qiankun qiankun是阿里开源的一个微前端的框架,在阿里内部已经经过一批线上应用的充分检验及打磨了,所以可以放心使用。
qiankun优势:
- 基于single-spa封装的,提供了更加开箱即用的API
- 技术栈无关,任意技术栈的应用均可使用/接入,不论是React/Vue/Angular/JQuery还是其他等框架。
- HTML Entry的方式接入,像使用iframe一样简单
- 实现了single-spa不具备的样式隔离和js隔离
- 资源预加载,在浏览器空闲时间预加载未打开的微应用资源,加速微应用打开速度。
qiankun
- 基座(主应用):主要负责集成所有的子应用,提供一个入口能够访问你所需要的子应用的展示,尽量不写复杂的业务逻辑
- 子应用:根据不同业务划分的模块,每个子应用都打包成umi模块的形式供基座(主应用)来加载
底层原理js沙箱使用的是proxy进行快照然后用用with(window)0包惠起来with内的window其实就是proxy.window我们声明变量varname='小满'实际这个变量挂到了proxy.window并不是真正的window css沙箱原理第一个就是shadowDom隔离第二个类似于Vue的scoped
硬链接和软链接
索引节点方式(硬链接)
多个链接的索引节点指针指向的是同一个文件,同时索引节点中设置一个链接计数count,用来表示链接到本索引节点上的用户目录项的数目 任何用户对共享文件进行的修改都会引起其相应结点内容的改变(如文件长度改变),其他用户也能看到改变,从而方便共享 当用户不再使用该文件的时候,就断开链接,count的值也随之改变(-1)
符号链接方式(软链接)
这种方式只有文件主才有指向索引结点的指针 共享文件的其他用户只有路径名,没有指向索引节点的指针 文件拥有者删除共享文件后,其他用户如果试图通过符号链访问该文件 系统会找不到该文件访问失败,然后删除符号链
软链接的链接计数恒为1
贡献者
版权所有
版权归属:PinkDopeyBug