Code Splitting - Libraries

A typical application uses third party libraries for framework/functionality needs. Particular versions of these libraries are used and code here does not change often. However, the application code changes frequently.

Bundling application code with third party code would be inefficient. This is because the browser can cache asset files based on the cache header and files can be cached without needing to call the cdn again if its contents don't change. To take advantage of this, we want to keep the hash of the vendor files constant regardless of application code changes.

We can do this only when we separate the bundles for vendor and application code.

Let's consider a sample application that uses momentjs, a commonly used time formatting library.

Install moment as follows in your application directory

npm install --save moment

index.js

var moment = require('moment');
console.log(moment().format());

We can bundle the application with webpack using the following config

webpack.config.js

var path = require('path');

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

On running webpack in your application, if you inspect the resulting bundle, you will see that moment and index.js have been bundled in bundle.js.

This is not ideal for the application. If the code in index.js changes, then the whole bundle is rebuilt. The browser will have to load a new copy of the new bundle even though most of it hasn't changed at all.

Multiple Entries

Let's try to mitigate this by adding a separate entry point for moment and name it vendor

var path = require('path');

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

On running webpack now, we see that two bundles have been created. If you inspect these though, you will find that the code for moment is present in both the files! The reason for that is moment is a dependency of the main application (e.g. index.js) and each entry point will bundle its own dependencies.

It is for this reason, that we will need to use the CommonsChunkPlugin.

CommonsChunkPlugin

This is a pretty complex plugin. It fundamentally allows us to extract all the common modules from different bundles and add them to the common bundle. If a common bundle does not exist, then it creates a new one.

We can modify our webpack config file to use the CommonsChunkPlugin as follows

  • webpack.config.js**
var webpack = require('webpack');
var path = require('path');

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

Now run webpack on your application. Bundle inspection shows that moment code is present only in the vendor bundle.

Implicit Common Vendor Chunk

You can configure a CommonsChunkPlugin instance to only accept vendor libraries.

webpack.config.js

var webpack = require('webpack');
var path = require('path');

module.exports = function() {
    return {
        entry: {
            main: './index.js'
        },
        output: {
            filename: '[name].[chunkhash].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

But, if we change application code and run webpack again, we see that the hash for the vendor file changes. Even though we achieved separate bundles for vendor and main bundles, we see that the vendor bundle changes when the application code changes. This means that we still don't reap the benefits of browser caching because the hash for vendor file changes on every build and the browser will have to reload the file.

The issue here is that on every build, webpack generates some webpack runtime code, which helps webpack do its job. When there is a single bundle, the runtime code resides in it. But when multiple bundles are generated, the runtime code is extracted into the common module, here the vendor file.

To prevent this, we need to extract out the runtime into a separate manifest file. Even though we are creating another bundle, the overhead is offset by the long term caching benefits that we obtain on the vendor file.

webpack.config.js

var webpack = require('webpack');
var path = require('path');

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

With the above webpack config, we see three bundles being generated. vendor, main and manifest bundles.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市绽左,隨后出現(xiàn)的幾起案子崇棠,更是在濱河造成了極大的恐慌绝骚,老刑警劉巖砰左,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件箭券,死亡現(xiàn)場離奇詭異允华,居然都是意外死亡井联,警方通過查閱死者的電腦和手機(jī)卜壕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來烙常,“玉大人轴捎,你說我怎么就攤上這事〔显啵” “怎么了侦副?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長驼鞭。 經(jīng)常有香客問我秦驯,道長,這世上最難降的妖魔是什么挣棕? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任汇竭,我火速辦了婚禮,結(jié)果婚禮上穴张,老公的妹妹穿的比我還像新娘细燎。我一直安慰自己,他們只是感情好皂甘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布玻驻。 她就那樣靜靜地躺著,像睡著了一般偿枕。 火紅的嫁衣襯著肌膚如雪璧瞬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天渐夸,我揣著相機(jī)與錄音嗤锉,去河邊找鬼。 笑死墓塌,一個(gè)胖子當(dāng)著我的面吹牛瘟忱,可吹牛的內(nèi)容都是我干的奥额。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼访诱,長吁一口氣:“原來是場噩夢啊……” “哼垫挨!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起触菜,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤九榔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后涡相,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哲泊,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年催蝗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了攻旦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡生逸,死狀恐怖牢屋,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情槽袄,我是刑警寧澤烙无,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站遍尺,受9級特大地震影響截酷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜乾戏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一迂苛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鼓择,春花似錦三幻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至摆出,卻和暖如春朗徊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背偎漫。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工爷恳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人象踊。 一個(gè)月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓温亲,卻偏偏與公主長得像棚壁,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子铸豁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,478評論 5 6
  • 曾經(jīng)有兩個(gè)他, 對我說:“你值得更好的人菊碟〗诮妫” 一個(gè)是18歲,我轉(zhuǎn)過頭摟著他的腰逆害,抬頭看著他的臉头镊,哭著說:“不管別人...
    浮生aureate閱讀 198評論 0 1
  • 關(guān)于勞逸結(jié)合的問題,我想魄幕,關(guān)于竭盡全力要不要休息的論斷是該消停了相艇,很簡單:星云法師自從加入弘法利生行列之后,近...
    智豪_5e4a閱讀 355評論 0 0
  • 應(yīng)當(dāng)根據(jù)什么標(biāo)準(zhǔn)區(qū)分新舊媒體纯陨?新媒體有什么特點(diǎn)和優(yōu)勢坛芽?是否可取代舊媒體? 一翼抠、新舊媒體區(qū)分 1咙轩、市場的差異。傳統(tǒng)媒...
    劉二傻閱讀 1,813評論 0 1