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

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

背景

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

咱们须要发布通过打包以后的代码吗

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

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

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

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

有可能,由于webpack插件能够配置exclude字段,若是项目的webpack配置exclude掉了node_modules,就会产生反作用。好比可能未经babel转码成es5代码(我发布的这个组件目前只会存在这样一种可能的反作用)。github

如何解决反作用

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

判断重复依赖的机制

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

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

我发布的包里面dependencies里包含element-ui,这没问题,我确实依赖了element-ui。那么install包时,会根据我写明的dependencies下载element-ui并放在包的node_modules里面。因此这个包引用的element-ui和项目自己引用的element-ui因为path不一样被认为是不一样的依赖,因而都被打包进了bundle里面形成了重复依赖。npm

如何解决

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

方法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点一、发布npm包的流程二、package.json中的module字段三、判断重复依赖的机制四、基于ui组件封装组件时如何避免重复依赖

相关文章
相关标签/搜索