In this section, we will discuss how webpack splits code using require.ensure()
.
require.ensure
is specific to webpack, seeimport()
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()
d 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)
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.
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.
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.
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 ouroutput.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
chunkName
require.ensure
relies onPromise
internally. See this section for possible polyfills.
require.ensure()
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.
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.
© 2012–2016 Tobias Koppers
Licensed under the Creative Commons Attribution License 4.0.
https://webpack.js.org/guides/code-splitting-require/