关于taro:解决taro小程序中引入axios包过大的问题

背景

咱们在应用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个方向:

  1. 构建工具的调整优化
  2. 批改源码,防止多余援用

具体计划

因而对应的解决方案有:

  1. 将axios上传到公有库中,删除掉对http.js的相干援用
  2. 利用npm包的patch机制,在@freud/http 中对axios源码进行批改,删除掉对http.js的相干援用
  3. @freud/http 拆分成2个npm包,别离对应web环境,小程序环境
  4. 改用webpack 对@freud/http进行打包
  5. 引入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配置,做到所有子包的根底构建配置雷同。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理