如何解决项目依赖重复打包问题


title: 如何解决项目依赖重复打包问题 tags: - webpack - vite categories: - 前端 author: 余腾靖

pubDatetime: 2024-03-22

由于最近面试经常被问到这个问题(简历上写了),感觉答的时候不是很系统清晰,于是便有了这篇文章。

为啥对这个问题这么上心?

在上家公司最后一段时间是做前端工程基建相关的,不说是最有成长的一段时间,但绝对是最开心的一段时间。上来第一个任务是优化项目构建体积,项目之前是 webpack 写的,做技术升级之后迁移到了 vite,包管理器也从 yarn1 迁移到 pnpm,但是迁移后发现主入口 bundle 的体积增加了很多,后面也是采用了多个方法对体积进行优化:

  • 去除重复依赖,有很多依赖由于引用到了不同版本被打包了多次,具体哪些包忘了,但是印象中 pnpm.overrides 很长
  • 按需导入,组件库是 ant design vue based,我知道最新版已经支持 tree-shaking,不需要配置按需导入,但当时项目用的版本很低了,毕竟还是 vue2。
  • 选择精简的版本,例如我们项目目只用到了 paper.js 的核心功能,但是默认 papermain 是指向 dist/paper-full.js(451KB) 你可以配置它指向 dist/paper-core.js(394KB)
  • 使用 importmap 将包从构建中分离,改为使用浏览器原生的 ESM 从 CDN 加载
  • 对于一些还在使用 rollup + babel 打包的 package 使用 babel-runtime 避免重复打包 helper 代码
  • 精准配置 browserslist,所有构建工具统一使用 package.jsonbrowserslist 字段读取浏览器兼容目标版本
  • 项目中同时使用了多个功能类型的 pkg,例如时间相关的 moment, dayjs, date-fns, 还有我记得生成二维码和处理 xlsx 的库也有多个,为了这个问题我还写了个 cli: find-similar-packages
  • 通知其它部门同事不要把 node_modules 打包到 dist 里面,把 ant design vuebabel-runtime 升级到 @babel/runtime,反正就是说有些包打包很不规范
  • ...

等等,离职混日子快半年了,暂时只能想起这些。

回到主题,在我所有的优化策略中,去除重复依赖减小打包体积的效果是占第二位的。第一位是 importmap,最简单的减小体积策略就是不打包。关于 importmap,有机会单独写一篇文章。

重复依赖是如何产生的?

在讨论之前,先介绍一些后面会提到的术语,确保我们在同一个频道上。

下面是一个典型的 monorepo 前端项目:

plaintext ./mono ├── apps // 应用级别的包 │ ├── mobile │ └── web ├── packages // 共享模块 │ ├── pkg1 │ ├── pkg2 │ ├── ui │ └── utils └── tools // 工具包 ├── eslint-config └── vite-config

apps, packages, tools 都叫 workspace, 里面 package 称之为 workspace packagemono 文件夹叫 root workspace

在包管理器的视角依赖可以分为两类:

  • 直接依赖:例如 workspace package uipackage.json 中声明的 axios
  • 间接依赖:例如 axios 依赖的 follow-redirects

按照用途分为两类:

  • 源码依赖:例如 apps/web/src 导入了 pkg1vuepkg1vue 以及它俩依赖树上的依赖称为源码依赖
  • 开发依赖:例如 vite, esbuild 不会被打包到 apps/web/dist 中的只在开发时使用的依赖,也包括它俩依赖树上的依赖

lockfile 的副作用

lockfile 可以帮我们确保安装的依赖完全一致,但是它却也是导致我们项目依赖安装多个版本的主要原因之一。

场景还原:

  1. 我们在 pkg1 中的 dependencies 声明 "foo": "^1.0.1"”,此时 foo 最新版本是 1.0.1,运行 pnpm install, 这时 lockfile 中写入了 pkg1foo 解析到的版本是 1.0.1,实际也是安装 1.0.1
  2. 某一天我们需要在 pkg2 中开发需求,pkg2 也要用到 foo,于是运行 pnpm --filter pkg2 add foo,在这段时间 foo 发布了 1.0.2,此时 pkg2 安装的就会是 1.0.2。我们的 app package 依赖 pkg1pkg2,于是打包 app 的时候就会打包 foo@1.0.1foo@1.0.2

你可能会说 pnpm 咋这么蠢,不会直接把 pkg1foo 也安装为 1.0.2 吗,1.0.2 是符合 ^1.0.1 的兼容性要求的呀。实际上按照我的理解,pnpm 之所以没这么做,是因为

  1. lockfile 里面已经声明了 pkg1foo 解析到的版本,所以会直接按照 lockfile 声明的版本来
  2. 因为 pkg 中 foo@1.0.1 之前已经验证测试时可用的,要是它帮你更新到 1.0.2 可能会出现 bug,为了确保项目的稳定默认不会帮你升级。semver 只是一个规范, 1.0.11.0.2 到底有没有引没有引入 breaking change 那你得去看 changelog 和源代码才能确定。

不兼容版本

一个很典型的例子就是去年 axios 发布了 1.x,项目中同时存在 0.x1.x。草,axios 这么古老的项目直到去年才发 1.x 你敢信?esbuildreact native 加把油,希望我退休之前能发 1.0

即便依赖树上的包在 dependencies 中声明 axios 的时候都使用了兼容性前缀 ^,但是对于这种不符合兼容性前缀的多个版本,pnpm 就没法通过后文会详细介绍的删 lockfile 重装或者跑 pnpm dedupe 来解决了。

除此之外还有换包名这种特殊情况,例如 babel-runtime -> @ba

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
禅道开源项目管理软件4.3.beta版本于08月05日正式发布,该版本主要完善批量操作、api和扩展的例子。调整插件管理功能。完善测试管理功能。 注:该版本为BETA版本,不建议用于生产环境 一、修改记录 完成的需求: 1156 在确认bug的时候可以设置bug的优先级 1155 处理发信逻辑,已经删除的用户不要再发送邮件 1154 参考论坛用户的建议,考虑实现浏览器贴图上传功能 1152 备注中添加的超链接在显示的时候被过滤掉了 1151 在禅道中增加对浏览器支持的说明 1150 用例导入模板页面,显示模板编号用于比对。 1127 打包的时候把扩展目录下面的css,js也都生成 1116 显示燃尽图的时候默认将周末去掉。 1111 web应用安装之后,页面不用刷新。改用ajax修改安装按钮的状态。 1108 从计划中移除需求的时候,正确处理其所处的阶段 1105 zentaotest, zentaotask,zentaostory单独设置flow。 1103 发信应该可以重新设置。 1102 调整组织视图用户界面各个功能页面的样式,保持统一 1101 完善升级逻辑,增加插件的兼容性处理。 1100 增加不兼容插件功能 1099 安装插件的时候,将确认按钮放在上面 1096 桌面提醒增加繁体版本 1088 在创建附件目录的时候,自动创建一个空白的index.html 1080 整理使用到的session列表 1078 禅道中有开始和结束日期的地方增加结束日期不能小于开始日期的检查 1074 作为测试人员,我需要在测试任务的详情里方便的查看测试版本需求 1072 用例的批量添加页面需要处理。 1070 项目视图的需求列表页面增加创建用例的链接 1069 添加完项目之后的弹出页面停留。 1068 在添加对象的时候,如果某个字段没有取值列表,给出相应的链接,并可局部刷新 1067 创建新的计划的时候选择最新的一个计划结束日期开始。 1066 创建应用的时候,判断是否有http:// 1065 批量添加用户的时候,第一个密码的同上按钮去掉。 1064 用户列表里面的最后登录时间去掉1970。 1063 添加用户的时候,没有带部门条件。(包括批量添加) 1062 部门的排序给默认数字。 1061 安装成功之后的首页,将项目和产品区块的背景色去掉。 1060 init.bat生成的ztcli.bat错误 1059 调整和修复任务、测试和需求扩展模块的代码 1057 重新梳理默认的权限列表 1056 没有批量编辑权限的情况下,把多选框去掉 1055 查看组织日志/TODO时,横向滚动时,锁定前两列的部门及员工姓名。 1053 启动任务的时候自动修改指派者 1052 测试任务的用例列表增加搜索功能 1049 备注编辑功能,只有最后一个备注才可以修改或者删除。 1045 详情页面的操作图标都加上提示。 1043 dao.class.php查询sql的时候自动增加deleted=0的条件 1042 增加bug的批量添加功能 1039 我的地盘里面的我的任务,bug,需求等增加批量操作。 1037 返回的按钮改为<<这种形式的? 1030 插件增加是否是官方出品字段 1029 创建项目的时候,关联产品使用chosen实现 1026 测试任务关联的用例版本发生变化之后,应当给予提示和确认。 1025 我的地盘中的用例增加执行功能,要判断是否是在测试任务中。 1022 添加需求,任务,bug,文档的时候判断是否重复。 1017 修复文档库当内容比较多的时候的页面框架变形的问题。 1010 我的地盘中的待办列表页面可以选择日期导入 1006 整理每个页面的标题和position 1005 各个列表页面的模块都可以折叠隐藏 1003 和禅道服务器进行交互的api都改为二级域名。 1002 和禅道服务器进行交互的api都加上语言选项 1000 从项目提交测试的bug自动修改其解决方案 994 重新设计项目列表的折叠和隐藏功能 986 批量添加的时候,将input改为textarea 981 调整各个对象编辑页面的标题文本框的排版 979 调整测试任务的详情页面,和其他的详情页面保持一致 971 将扩展编辑器放在插件菜单下面。 967 任务列表增加导入按钮 925 创建产品、需求的时候 复责人、评审人建议过滤closed 918 草稿需求阶段在取消计划和取消项目关联的时候没有处理 872 测试用例导出的数据 没有用例的执行结果 871 测试人员创建bug的时候可以选择没有权限的项目,但是创建bug之后却看不到,导致重复提交 853 实现需求测试用例覆盖率功能 826 在禅道中提供api方面的实际例子 746 使用ajax实现列表页面的删除或者移除功能 680 增加依赖插件的功能 586 优化批量添加用例时的需求列表 562 测试用例增加csv格式的导入功能 404 调整统计报表的展示形式 379 完善部门删除的逻辑 130 完善需求列表页面增加批量操作 122 计划中关联bug 修复的BUG: 451 【查询用例】执行用例的时候,不方便查看上一次的用例执行结果,建议将用例执行结果表单链接在用例的下方 453 激活bug时备注内容没有处理html代码,导致保存后页面布局严重混乱。   功能截图 1、Windows一键安装包的新的控制面板 到xampp目录中,点击start.bat,运行。 2、桌面提醒工具 禅道软件的下方有“下载桌面提醒工具”的链接,点击可以下载。 解压后,点击notify.bat,运行。 3、导出是增加导出选中。 选中想要导出的条目,点击导出。 可以只导出选中的条目。 4、精简顶部菜单。 5、为了方便人们选择,增加成员维护列表。 可以维护成员列表,以便使用。
1.[今日课程内容总览] Maven--***** 介绍 优点 用maven创建一个项目, 用maven创建一个ssm项目,每一层的代码分开,把一个项目拆解成多个项目 2.[今日包含笔记] maven介绍: Eclise: 缺点: Jar包: 版本管理,解决jar包冲突:删除老的jar包,保留新的jar包 不同的项目,jar包要复制一份;Users Library 羡慕yum的好处,安装软件,自动下载,自动验证,自动安装,自动测试;镜像网站 Jar包的依赖: 致命的缺点:现象: 每一个项目都有前台(广大网民)和后台(管理员看的),后台的功能远远的大于>前台的功能;迭代升级;每次升级都要重启tomcat;将tomcat做很多个备份(10个),为了nginx转发;前台:访问比较大,管理员访问量比较小; 问题: 每次升级,10个tomcat都升级一次 后台的升级频繁要比前台频繁;升级10次,9次改的是后台的代码,只有一次是前台的代码 解决方案: 是将前台(广大网民看的页面)的代码和后台(管理员)的代码要分开,将原来的一个项目分别放到两个web项目;一个web项目一个tomcat;好处:更新的时候如果更新后台(管理员),只需要重启后台的tomcat(服务); 折成两个项目以后的缺点:Service以下的代码重复; 将Service层以下的代码放到一个新创建的java项目中,在部署的时候将Service(java项目)打成一个jar包,分别放到两个web服务中;编译的时候让web项目依赖与Service(java项目)_source folder;配置麻烦,项目项目之间的依赖头脑得相当清晰 这个缺点Maven解决了; 请听今天的内容 拆分前:图一 拆分后是图二 3. 介绍 官网:http://maven.apache.org/download.cgi 目录介绍: Bin:二进制文件 Boot:引导,启动 Conf:配置文件 Lib:jar包 README.txt:读我 3.1.修改配置文件的内容 路径:%MAVEN_HOME%\conf\settings.xml 配置文件代码: d:/repo alimaven aliyun maven http://maven.aliyun.com/nexus/content/groups/public/ central 注意: 千万不要将文档中的setting的内容全部替换到maven中的内容,要对比着修改,保留原来的; 只修改本地仓库,和下载镜像(源) 3.2.Eclipse Maven的配置 每打开一个新的工作空间,要配置一下Maven,然后再写代码 3.3.创建Maven项目 右击创建一个maven project Packing:有三种: Jar:java项目, War:web项目 Pom:文件夹,jar和war文件,mavenProject:一个项目,可以放jar和war包,通过pom,一般新创建的maven Project是POM 3.4.创建一个Maven Model 最外面的项目是MavenProject,其它的全部是Maven Model 3.4.1.创建JAR 目录介绍: Mvn-jar |-->Src:源码:java代码 |-->|-->main:代码:除测试以外的代码:junit |-->|-->main|-->java:代码 |-->|-->main|--
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值