背景
咱们在应用taro 和 @freud/http
(公司外部我的项目,基于axios做的二次开发) 的时候,发现构建产物中多了很多没有用的包,导致产物变大了150kb左右。
通过一番搜寻,发现是因为taro小程序不能解析package.json中的browser module等字段,而@frued/http 因为要同时反对web和小程序环境,而axios中就有browser属性:
"browser": {
"./lib/adapters/http.js": "./lib/adapters/xhr.js"
},
所以在taro中引入axios的时候,会将 lib/adapters/http.js
也打包进来,http.js中会有很多依赖包如zlib等等,就会导致上述包过大的问题。
解决思路
首先咱们能够定位到axios源码相干的地位:
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = require('./adapters/xhr');
} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
// For node use HTTP adapter
adapter = require('./adapters/http');
}
失常状况下,在web环境中,./lib/adapters/http.js
会被 ./lib/adapters/xhr.js
替换
所以以上代码在打包之后就会变成。
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = require('./adapters/xhr');
} else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') {
// For node use HTTP adapter
adapter = require('./adapters/xhr');
}
咱们在晓得了失常状况下,构建产物应该长什么样子之后,再来看咱们目前的构建产物。
因为@frued/http 是基于rollup做的构建,所以产物如下图:
index.js中保留对axios的援用 var axios = require('axios')
,而axios的对应lib/default.js
中,仍然在援用 adapter/http
图一
图二
至此,咱们大抵有了解决问题的2个方向:
- 构建工具的调整优化
- 批改源码,防止多余援用
具体计划
因而对应的解决方案有:
- 将axios上传到公有库中,删除掉对http.js的相干援用
- 利用npm包的patch机制,在
@freud/http
中对axios源码进行批改,删除掉对http.js的相干援用 - 将
@freud/http
拆分成2个npm包,别离对应web环境,小程序环境 - 改用webpack 对
@freud/http
进行打包 - 引入rollup插件
1-3 很简略,不必细讲。先讲一讲第四点,为什么应用webpack就能够解决这个问题。
rollup中为了更好地做tree shaking,因而只保留着对依赖的援用,而不是间接将依赖的代码打包到index.js中(见图一)。所以@freud/http
引入axios时,axios的代码仍然保留着对http.js的援用,只有到理论web我的项目运行时,browser字段失效,则http.js被xhr.js替换。
然而webpack构建时,会主动解析模块内容,将所有模块打包后的内容和id以key value的模式存在于构建产物的一个数组中,此时http.js就会被xhr.js替换。
故因为对依赖包的解决形式不同,webpack构建即可解决此问题。
第五点,尚在钻研中,有基于rollup做二次封装的构建工具bili 解决了这个问题。
结尾
因为 @freud/http
为monorepo我的项目,对立应用rollup构建。若所有包都改用webpack构建,则老本太大。基于此,我抉择了在subpage中增加webpack做二次构建的形式,即在rollup将@freud我的项目中的子包构建完之后,再执行@freud/http
中的webpack构建命令,将rollup的构建产物lib/index.js 用webpack再构建一次。这样可能防止在子项目中再写一遍babel配置,做到所有子包的根底构建配置雷同。
发表回复