Code Splitting - Using require.ensure

In this section, we will discuss how webpack splits code using require.ensure().

require.ensure is specific to webpack, see import() for a proposal for ECMAScript.

require.ensure()

webpack statically parses for require.ensure() in the code while building. Any module that is referenced as a dependency or require() within the callback function, will be added to a new chunk. This new chunk is written to an async bundle that is loaded on demand by webpack through jsonp.

The syntax is as follows:

require.ensure(dependencies: String[], callback: function(require), chunkName: String)

dependencies

This is an array of strings where we can declare all the modules that need to be made available before all the code in the callback function can be executed.

callback

This is the callback function that webpack will execute once the dependencies are loaded. An implementation of the require function is sent as a parameter to this function. The function body can use this to further require() modules it needs for execution.

chunkName

The chunkName is a name given to the chunk created by this particular require.ensure(). By passing the same chunkName to various require.ensure() calls, we can combine their code into a single chunk, resulting in only one bundle that the browser must load.

Example

Let us consider the following file structure:

.
├── dist
├── js
│   ├── a.js
│   ├── b.js
│   ├── c.js
│   └── entry.js
└── webpack.config.js

entry.js

require('./a');
require.ensure(['./b'], function(require){
    require('./c');
    console.log('done!');
});

a.js

console.log('***** I AM a *****');

b.js

console.log('***** I AM b *****');

c.js

console.log('***** I AM c *****');

webpack.config.js

var path = require('path');

module.exports = function(env) {
    return {
        entry: './js/entry.js',
        output: {
            filename: 'bundle.js',
            path: path.resolve(__dirname, 'dist'),
            publicPath: 'https://cdn.example.com/assets/',
            // tell webpack where to load the on-demand bundles. 

            pathinfo: true,
            // show comments in bundles, just to beautify the output of this example.
            // should not be used for production.
        }
    }
}

output.publicPath is an important option when using code-splitting, it is used to tell webpack where to load your bundles on-demand, see the configuration documentation.

On running webpack on this project, we find that webpack has created two new bundles, bundle.js and 0.bundle.js.

entry.js and a.js are bundled in bundle.js.

bundle.js

/******/ (function(modules) { // webpackBootstrap
//webpack bootstrap code...

/******/     // __webpack_public_path__
/******/     __webpack_require__.p = "https://cdn.example.com/assets/";

// webpack bootstrap code...
/******/ })
/******/ ([
/* 0 */
/* unknown exports provided */
/* all exports used */
/*!*****************!*\
  !*** ./js/a.js ***!
  \*****************/
/***/ (function(module, exports) {

console.log('***** I AM a *****');


/***/ }),
/* 1 */,
/* 2 */,
/* 3 */
/* unknown exports provided */
/* all exports used */
/*!*********************!*\
  !*** ./js/entry.js ***!
  \*********************/
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(/*! ./a */ 0);
__webpack_require__.e/* require.ensure */(0).then((function(require){
    __webpack_require__(/*! ./c */ 2);
    console.log('done!');
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);


/***/ })
/******/ ]);

We can see the specified webpack public path on webpack_require.p in the bootstrap code, it corresponds to our output.publicPath configuration on above.

b.js and c.js are bundled in 0.bundle.js.

0.bundle.js

webpackJsonp([0],[
/* 0 */,
/* 1 */
/* unknown exports provided */
/* all exports used */
/*!*****************!*\
  !*** ./js/b.js ***!
  \*****************/
/***/ (function(module, exports) {

console.log('***** I AM b *****');


/***/ }),
/* 2 */
/* unknown exports provided */
/* all exports used */
/*!*****************!*\
  !*** ./js/c.js ***!
  \*****************/
/***/ (function(module, exports) {

console.log('***** I AM c *****');



/***/ })
]);

Now just add bundle.js in your HTML file and open it in your broswer, the 0.bundle.js will be loaded on demand (from https://cdn.example.com/assets/0.bundle.js) by webpack.

More examples

Promise polyfill

require.ensure relies on Promise internally. See this section for possible polyfills.

Gotchas for require.ensure()

Empty Array as Parameter

require.ensure([], function(require){
    require('./a.js');
});

The above code ensures that a split point is created and a.js is bundled separately by webpack.

Dependencies as Parameter

require.ensure(['./b.js'], function(require) {
    require('./c.js');
});

In the above code, b.js and c.js are bundled together and split from the main bundle. But only the contents of c.js are executed. The contents of b.js are only made available and not executed. To execute b.js, we will have to require it in a sync manner like require('./b.js') for the JavaScript to get executed.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市飒箭,隨后出現(xiàn)的幾起案子誊薄,更是在濱河造成了極大的恐慌娘荡,老刑警劉巖循榆,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件队丝,死亡現(xiàn)場離奇詭異局骤,居然都是意外死亡虾宇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門簇搅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來完域,“玉大人,你說我怎么就攤上這事瘩将∫魉埃” “怎么了凹耙?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肠仪。 經(jīng)常有香客問我肖抱,道長,這世上最難降的妖魔是什么异旧? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任意述,我火速辦了婚禮,結(jié)果婚禮上吮蛹,老公的妹妹穿的比我還像新娘荤崇。我一直安慰自己,他們只是感情好潮针,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布术荤。 她就那樣靜靜地躺著,像睡著了一般然低。 火紅的嫁衣襯著肌膚如雪喜每。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天雳攘,我揣著相機(jī)與錄音,去河邊找鬼枫笛。 笑死吨灭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的刑巧。 我是一名探鬼主播喧兄,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼啊楚!你這毒婦竟也來了吠冤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤恭理,失蹤者是張志新(化名)和其女友劉穎拯辙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颜价,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涯保,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了周伦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夕春。...
    茶點(diǎn)故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖专挪,靈堂內(nèi)的尸體忽然破棺而出及志,到底是詐尸還是另有隱情片排,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布速侈,位于F島的核電站率寡,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏锌畸。R本人自食惡果不足惜勇劣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望潭枣。 院中可真熱鬧比默,春花似錦、人聲如沸盆犁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谐岁。三九已至醋奠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伊佃,已是汗流浹背窜司。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留航揉,地道東北人塞祈。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像帅涂,于是被迫代替她去往敵國和親议薪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評論 2 350

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