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
ます 図1図 2
これまでのところ、この問題を解決するには、おおまかに 2 つの方向性があります。
- ビルド ツールの微調整と最適化
- 冗長な参照を避けるためにソース コードを変更する
具体的な計画
したがって、対応するソリューションは次のとおりです。
- axios をプライベート ライブラリにアップロードし、関連する http.js への参照を削除します。
- npm パッケージのパッチ メカニズムを使用して、
@freud/http
の axios ソース コードを変更し、http.js への関連する参照を削除します。 @freud/http
Web 環境とアプレット環境にそれぞれ対応する 2 つの npm パッケージに分割@freud/http
パッケージングには代わりに webpack を使用してください- ロールアップ プラグインを導入する
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配置,做到所有子包的基础构建配置相同。