ライブラリのコード分離

5172 ワード

一般的なアプリケーションでは、フレームワーク/機能の要件を満たすためにサードパーティ製ライブラリが使用されます.これらのライブラリの特定のバージョンを使用し、頻繁に変更することはありません.しかし、一方でアプリケーションコードは頻繁に変更されています.
サードパーティ製コードをアプリケーションにバンドルするのは非効率です.ブラウザはキャッシュヘッダに基づいてキャッシュできるため、キャッシュされたリソースファイルをキャッシュし、その内容が変更されない場合にcdnを再呼び出す必要はありません.これを利用して、アプリケーションコードがどのように変化しても、サードパーティファイルのハッシュ値を一定に保つことを望んでいます.
サードパーティ製パッケージとアプリケーションコードのパッケージを個別にパッケージ化する場合にのみ、これを行うことができます.
このサンプルプログラムmomentjs、一般的な時間フォーマットライブラリを見てみましょう.
以下に示すように、あなたのアプリケーションにmomentをインストールします.npm install --save moment
indexファイルでrequiremomentを依存として出力し、現在の時間を以下に示します.
index.js
var moment = require('moment');
console.log(moment().format());


Webpackと次の構成でアプリケーションをパッケージ化できます.
webpack.config.js
var path = require('path');

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

アプリケーションでwebpackを実行し、実行する構造パッケージをチェックすると、momentindex.jsbundle.jsにパッケージ化されていることがわかります.
これは理想的な効果ではありません.index.jsのコードが変更されると、パケット全体が再構築されます.ブラウザは、ほとんど変更されていない場合でも、新しく構築されたパッケージのコピーをロードする必要があります.
マルチエントランス
では、momentに別のエントリポイントを追加し、vendorと名前を付けて最適化してみましょう.
webpack.config.js
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つのパッケージが作成されていることがわかります.この2つのパケットをチェックすると、momentのコードが2つのパケットに存在することがわかります!
そのため、プラグインを使用する必要があります.CommonsChunkPlugin
これは非常に複雑なプラグインです.異なるパッケージからすべての共通モジュールを抽出し、共通パッケージに追加できます.パブリックパッケージが存在しない場合は、新しいパッケージがパブリックパッケージとして作成されます.
Webpackの構成を以下のように変更することで、CommonsChunkPluginプラグインを使用できます.
webpack.config.js
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.momentコードはvendorパケットにのみ存在する.
暗黙汎用vendorブロックCommonsChunkPluginインスタンスを構成してvendorライブラリのみを受け入れることができます.
webpack.config.js
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;
                }
            })
        ]
    };
}

インベントリファイル
しかし、現在アプリケーションコードを変更し、webpackを再実行すると、vendorファイルのhash値が変更されたことがわかります.vendorパッケージ・パッケージとmainパッケージの個別パッケージ化を実現しても、アプリケーションコードが変更された場合vendorパッケージは依然として変化していることがわかります.
これは、vendorファイルのhash値がコンストラクションのたびに変更されるため、ブラウザキャッシュを使用していないことを意味します.これにより、ブラウザはファイルを再ロードする必要があります.
私たちが直面している問題は、構築のたびに、webpackが実行時コードを生成し、webpackの作業に役立つことです.単一のパケットのみがある場合、実行時コードはパケットに保持されます.しかし、複数のbundleを生成すると、実行時のコードが共通モジュールに抽出され、私たちの「vendor」ファイルになります.
このようなことを阻止するためには、ランタイムコードを別のリストファイルに抽出する必要があります.別のパッケージを作成する追加のオーバーヘッドがあっても、「vender」ファイルの長期キャッシュよりもメリットが大きいのは明らかです.
webpack.config.js
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.
            })
        ]
    }
};

以上のwebpack構成に基づいて、vendor,mainおよびmanifestの3つのパケットが生成することが分かる.
長期パケットキャッシュは、ハッシュポリシー「chunkhash」によって実現されることに留意されたい.もっと勉強しなさい
上一篇:CSSのコード分離