ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

减小发布到npm包的体积与避免重复依赖

2021-09-15 11:01:20  阅读:217  来源: 互联网

标签:npm 减小 依赖 element ui 组件 体积 打包


这两天一直在忙于封装一个vue table组件并发布到npm,记录一下我是如何把npm包的大小从100多kb减小到不足1kb的过程。

背景

这个组件底层依赖于element-ui,使用了其table组件和pagination组件,最终的组件是一个完全通过配置来描述每一列的表格组件。最开始我发布的是打包之后的代码。如果使用的这个组件的项目中没有引入过element-ui组件,那么不会造成任何重复的依赖,直接引用打包后的版本。但是如果项目本身已经引入了完整的element-ui(我们公司使用这个组件的10余个系统均引入了完整的element-ui),那么很明显会造成代码的重复,会使bundle增加90kb(未压缩时)。

我们需要发布经过打包之后的代码吗

如果发布的经过打包后的组件,是没办法避免重复依赖的。如果可以像把源代码直接copy到项目再import引入这样,就可以避免重复的依赖了。这个可以使用package.json中的module字段来完成。

当package.json中存在module字段时,会优先寻找module对应的文件,并使用ES模块规范处理。

我们可以把未经过打包的源代码发布到npm,并把package.json中的module字段指向源代码,这样引入的package就交由项目的构建工具(webpack, babel)来进行处理,因此理论上就可以避免重复依赖了。

使用module字段是否会有副作用

有可能,因为webpack插件可以配置exclude字段,如果项目的webpack配置exclude掉了node_modules,就会产生副作用。比如可能未经babel转码成es5代码(我发布的这个组件目前只会存在这样一种可能的副作用)。

如何解决副作用

  1. babel转码后再发布
  2. 在readme中指出,让用户取消掉babel的exclude

判断重复依赖的机制

到目前为止,还并不能解决重复依赖的问题。。。这是因为重复依赖的判断机制.Node.js中相同模块是否会被加载多次?

nodeJs是根据模块的路径来判断是否为同一依赖的,而大家都知道node.js会从当前模块所在目录的node_module开始找起,如果没找到再会去找上级目录的node_modules,直到根目录为止。那么问题就来了。

我发布的包里面dependencies里包含element-ui,这没问题,我确实依赖了element-ui。那么install包时,会根据我写明的dependencies下载element-ui并放在包的node_modules里面。所以这个包引用的element-ui和项目本身引用的element-ui由于path不同被认为是不同的依赖,于是都被打包进了bundle里面造成了重复依赖。

如何解决

方法1,在项目的babel配置中添加按需引入element-ui的配置,但是这个方法需要修改项目的配置,比较繁琐,我维护的10来个系统需要一个一个去改,太麻烦了。。。。

方法2,很简单,把发布的包的package.json的dependencies的element-ui和Vue删掉,这样npm install的时候就不会下载element-ui到包的node_modules,就是往上级目录找,直到项目node_modules里面的element-ui,这样,包引用的element-ui和项目引用的element-ui就是同一个依赖,就不会重复打包这和vue-cli3打包的库不会包含Vue依赖是同一个原理。最终的结果就是最终生产环境打包后的chunk-vender.js仅仅增加了不到1kb。

不过这样也造成了一定的问题,那就是本身不使用element-ui的项目需要手动引入打包之后的发布的文件。不过不使用element-ui组件的项目使用这个表格组件的收益和概率都不高,如果真的要用的话,单独再发布一个完全打包之后的包,也能快速解决问题。

总结

通过这两天的折腾,主要收获有4点
1、发布npm包的流程
2、package.json中的module字段
3、判断重复依赖的机制
4、基于ui组件封装组件时如何避免重复依赖

相关资源:npm-up:优雅地检查npm上最新的依赖项版本,然后执行所需的任何操作...

标签:npm,减小,依赖,element,ui,组件,体积,打包
来源: https://blog.csdn.net/sd19871122/article/details/120303999

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有