解决taro小程序包中axios包过大导致产品变大150kb左右的问题。经过一番查找,发现taro小程序无法解析package.json中的browser模块等字段,而@frued/http支持web和小程序两种环境,axios中有一个browser属性:"browser":{"./lib/adapters/http.js":"./lib/adapters/xhr.js"},所以taro引入axios时,lib/adapters/http.js也会被打包,http.js中会有很多依赖包,比如zlib等,就会导致上面提到的包太大的问题。解决思路首先,我们可以定位到axios源码的相关位置:}elseif(typeofprocess!=='undefined'&&Object.prototype.toString.call(process)==='[objectprocess]'){//对于节点使用HTTP适配器adapter=require('./adapters/HTTP');}一般情况下,在web环境下,./lib/adapters/http.js会被./lib/adapters/xhr.js代替,所以打包后会变成上面的代码。if(typeofXMLHttpRequest!=='undefined'){//对于浏览器使用XHR适配器adapter=require('./adapters/xhr');}elseif(typeofprocess!=='undefined'&&Object.prototype.toString.call(process)==='[objectprocess]'){//对于节点使用HTTP适配器adapter=require('./adapters/xhr');我们知道正常情况下构建产品应该是什么样子之后,我们来看一下我们当前的构建产品。因为@frued/http是基于rollup构建的,所以产品如下:index.js保留了对axios的引用varaxios=require('axios'),而axios对应的lib/default.js仍然引用了Adapter/http图1图2至此,我们解决问题的方向大致有两个:调整优化构建工具,修改源码,避免冗余引用具体解决方案所以对应的解决方案是:上传axios到私有库,删除去掉http.js的相关引用利用npm包的patch机制修改@freud/http中的axios源码,删除http.js的相关引用并将@freud/http拆分成两个npm包,分别对应web环境,小程序环境改为webpack对@freud/http进行打包,引入rollup插件1-3。很简单,不需要细说。先说第四点,为什么用webpack可以解决这个问题。为了在rollup中更好地做treeshaking,只保留对依赖项的引用,而不是直接将依赖代码打包到index.js中(见图1)。所以@freud/http在引入axios的时候,axios的代码还是保留了对http.js的引用。只有当实际的web项目运行时,浏览器字段才会生效,然后http.js被xhr.js代替。但是webpack在构建的时候默认会解析依赖包中的browser字段(见下图)。这时候http.js就会被xhr.js取代。由于对依赖包的处理方式不同,webpack构建可以解决这个问题。.第五点还在研究中,有一个基于rollup进行二次打包的构建工具bili可以解决这个问题。最后因为@freud/http是一个monorepo项目,所以统一使用rollup搭建。如果所有的包都改用webpack来构建,那么成本就太高了。基于此,我选择在子页面中添加webpack进行二次构建,即rollup在@freud项目中构建分包后,再在@freud/http中执行webpack构建命令构建rollup产品lib/index。js是用webpack重新构建的。这样可以避免在子项目中重新编写babel配置,使所有子包的基本构建配置相同。
