Webpack Code Splitting - Libraries

5121 ワード

Code Splitting - Libraries
ドキュメント・アドレス・アプリケーションでは、通常、サードパーティのクラス・ライブラリが使用されます.これらのクラス・ライブラリは、頻繁に変更されません.デルのビジネスコードは、ビジネスの変化に伴って常に更新する必要があります.Webappは効率を向上させるためにcache headerのパラメータに基づいてファイルをキャッシュし、ファイルキャッシュ後にcdnから新しいリソースを引き出す必要はありません.キャッシュプロパティを使用するには、ビジネスコードがどのように変更されても、変わらないvendorファイルを再ダウンロードしたくないvendorファイルをキャッシュする必要があります.この特性はvendor bundleとアプリケーションbundleにコードを分離することで使用できます.
シングルエントリ構成
アプリケーションで使用する(momentjs)[https://www.npmjs.com/package/moment]を使用して、時間をフォーマットするjsクラス.moment,https://www.npmjs.com/package/momentを取り付ける.indexでjsにはmomentが導入され、現在の時間を印刷するために使用される.
//index.js
var moment = require('moment');
console.log(moment().format());

次の構成でパッケージング
var path = require('path');

module.exports = function(env) {
    return {
        entry: './index.js',
        output: {
            filename: '[chunkhash].[name].js',
            path: path.resolve(__dirname, 'dist')
        }
    }
}
webpackを実行してパッケージ化した後、resulting bundleを分析すると、momentindex.jsが同じファイルにパッケージ化されていることがわかります(bundle.js).
上記のスキームは、index.jsコードが変わり、それに関連するbundleは、再コンパイルされます.多くのbundleは変更されていませんが、ブラウザはすべてのbundleを再ロードします.
マルチエントリ構成(Multiple Entries)momentvendorとを分離する、indexの変更を実現する.jsはvendorに影響しません.
var path = require('path');

module.exports = function(env) {
    return {
        entry: {
            main: './index.js',
            vendor: 'moment'
        },
        output: {
            filename: '[chunkhash].[name].js',
            path: path.resolve(__dirname, 'dist')
        }
    }
}

上記の構成に従って、webpackを実行すると、2つのbundleが生成されます.この2つのbundleファイルを表示すると、両方のファイルにmomentファイルが含まれています.これは、momentがメインプログラム(index.js)に依存するためである.したがって、2つのentry pointにはmomentが現れる.このような構成は私たちの予想を実現していません.この問題を解決するにはCommonsChunkPluginを使用する必要があります
CommonsChunkPlugin
このpluginは少し複雑で、pluginを使用して異なるbundleの共通モジュールを抽出して共通のbundleに置くことができます.共通のbundleが存在しない場合は、新しいbundleが作成されます.以下の構成を用いるCommonsChunkPluginを有効にする.
var webpack = require('webpack');
var path = require('path');

module.exports = function(env) {
    return {
        entry: {
            main: './index.js',
            vendor: 'moment'
        },
        output: {
            filename: '[chunkhash].[name].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor' // Specify the common bundle's name.
            })
        ]
    }
}

上記の構成により、webpackを実行し、パッケージされたbundleを表示します.momentコードはvendor bundleにのみ存在します.これによりindex.jsの修正により、すべてのファイルが再パッケージされることはありません.
Implicit Common Vendor Chunk CommonsChunkPluginはvendor libにのみ機能するように構成することができる.
var webpack = require('webpack');
var path = require('path');

module.exports = function() {
    return {
        entry: {
            main: './index.js'
        },
        output: {
            filename: '[chunkhash].[name].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                name: 'vendor',
                minChunks: function (module) {
                   // this assumes your vendor imports exist in the node_modules directory
                   return module.context && module.context.indexOf('node_modules') !== -1;
                }
            })
        ]
    };
}

Manifest File webpackコマンドを再実行するとvendorファイルのhash値が変更されます.vendormain bundleは構成によって分割されたが.しかし、ビジネスコードが変更されると、vendor bundleも変更されることが観察された.これにより、ブラウザのキャッシュ機能は使用できません.このような状況は、構築するたびに、webpackが実際にユーザーにアクセスするコンテンツを提供するためにruntime codeに依存する必要があるためです.単独bundleが1つしかない場合、runtime codeはbundleに含まれます.しかし、複数のbundlesが生成されると、runtime codeは共通のmodule(ここではvendorファイル)に抽出される.vendorに抽出されるため、トラフィックコードの変更はvendorに影響を与える.
この問題を回避するためにruntimeコードを別のmanifestファイルに分割する必要があります.これによりbundleファイルが複数生成されますが、ブラウザのキャッシュメカニズムが使用できます.具体的な構成は以下の通りです.
var webpack = require('webpack');
var path = require('path');

module.exports = function(env) {
    return {
        entry: {
            main: './index.js',
            vendor: 'moment'
        },
        output: {
            filename: '[chunkhash].[name].js',
            path: path.resolve(__dirname, 'dist')
        },
        plugins: [
            new webpack.optimize.CommonsChunkPlugin({
                names: ['vendor', 'manifest'] // Specify the common bundle's name.
            })
        ]
    }
};

上記の構成を使用すると、3つのbundles、vendormainmanifestの3つのbundlesが生成されます.