複数のルートを持つ単一ページ アプリを開発しており、それらのルートのごく一部がウィジェットを画面に描画します。各ルートには、コンテンツの描画を担当する遅延ロードされた React コンポーネントがあります。
私が使用しているウィジェット npm パッケージはかなり大きいので、メイン アプリケーションにバンドルしたくありませんが、それを必要とするルートのすべての動的バンドルにも含めたくありません。
この目的のために、Webpack 1.x では、ルートに対して次のことができました。
function loadComponentForRouteA() {
return function (location, callback) {
require.ensure([], (require) => {
require('widget-package');
require.ensure([], (require) => {
callback(null, require('path/To/Route/Component/A'));
}, "nameOfRouteBundleA");
}, "nameOfWidgetPackageBundle");
}
}
function loadComponentForRouteB() {
return function (location, callback) {
require.ensure([], (require) => {
require('widget-package');
require.ensure([], (require) => {
callback(null, require('path/To/Route/Component/B'));
}, "nameOfRouteBundleB");
}, "nameOfWidgetPackageBundle");
}
}
これにより、3 つの webpack バンドル ファイルが適切に生成されます。
- nameOfWidgetPackageBundle.js
- nameOfRouteBundleA.js
- nameOfRouteBundleB.js
そして、アプリで /route/A を押すと、nameOfWidgetPackageBundle.js と nameOfRouteBundleA.js の 2 つの js ファイルが順番に読み込まれます。
その後、/routeB に移動すると、nameOfWidgetPackageBundle.js と nameOfRouteBundleA.js の 2 つの js ファイルが順番にロードされますが、重要なことに、nameOfWidgetPackageBundle.js はブラウザーのキャッシュから取得されます...
Webpack 2.x 構文に変更した後、ルートは次のようになりました。
function loadComponentForRouteA() {
System.import('widget-package')
.then(widgetPackage => {
System.import('path/To/Route/Component/A')
.then(Component => {
callback(null, Component);
});
});
}
function loadComponentForRouteB() {
System.import('widget-package')
.then(widgetPackage => {
System.import('path/To/Route/Component/B')
.then(Component => {
callback(null, Component);
});
});
}
これにより、いくつかのchunkFilesが生成されます(厄介なことに、Webpack 2のSystem.importではチャンクファイルに名前を付けることができなくなりましたが、例のためにWebpack 1のrequire.ensureと同じバンドル命名スタイルを使用します):
- nameOfWidgetPackageBundleA.js
- nameOfWidgetPackageBundleB.js
- nameOfRouteBundleA.js
- nameOfRouteBundleB.js
そのため、基本的に、ウィジェット パッケージ用に重複したバンドルが作成されます。2 つのファイルのファイル サイズは同じで、内容もほぼ同じですが、異なるルート間を移動するには、使用するたびにウィジェット パッケージを再ダウンロードする必要があります。
ここでの私の質問は、Webpack 2 System.import を強制的に Webpack 1 の require.ensure のように動作させ、重複したバンドルを生成しないようにする方法を知っている人はいますか?
編集-問題を解決するために、次のwebpackプラグインを使用してみました:
new CommonsChunkPlugin({ name: 'widget-package', async: true, children: true, minChunks: 1}) (widget-package をエントリとして追加)
new DedupePlugin()
新しい webpack.optimize.AggressiveMergingPlugin({ minSizeReduce: 1.5, moveToParents: false, entryChunkMultiplicator: 10 })
これらのうち、効果があったのは AggressiveMergingPlugin だけでした。重複するウィジェットパッケージバンドルの問題を解決しましたが、動的バンドルが1つしかないため、すべての動的バンドルをマージして目的全体を無効にしました...