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

148次阅读

共计 1915 个字符,预计需要花费 5 分钟才能阅读完成。

背景

咱们在应用 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 配置,做到所有子包的根底构建配置雷同。

正文完
 0