taro アプレットで axios パッケージが大きすぎる問題を解決

taro アプレットで axios パッケージが大きすぎる問題を解決

バックグラウンド

taro and @freud/http(社内プロジェクト、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 ソース コードに関連する場所を特定できます。

  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 はロールアップに基づいて構築されているため、製品は次のようになります: Index.js は axios への参照を保持しますがvar axios = require('axios')、対応する axios はlib/default.js引き続き参照されadapter/httpます 図1Jgh5vobkfj.png図 27239D0F0-9C7C-47BA-A688-A390371FEFB6.png

これまでのところ、この問題を解決するには、おおまかに 2 つの方向性があります。

  1. ビルド ツールの微調整と最適化
  2. 冗長な参照を避けるためにソース コードを変更する

具体的な計画

したがって、対応するソリューションは次のとおりです。

  1. axios をプライベート ライブラリにアップロードし、関連する http.js への参照を削除します。
  2. npm パッケージのパッチ メカニズムを使用して、@freud/httpの axios ソース コードを変更し、http.js への関連する参照を削除します。
  3. @freud/httpWeb 環境とアプレット環境にそれぞれ対応する 2 つの npm パッケージに分割
  4. @freud/httpパッケージングには代わりに webpack を使用してください
  5. ロールアップ プラグインを導入する

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配置,做到所有子包的基础构建配置相同。

おすすめ

転載: juejin.im/post/7040821404782034980
おすすめ