It's easier to understand what it does by looking at the code it generates. I disabled minification at my lunr-demo and this is what I got:
app.ff56587996e597e4d868.js
functionloadIndex() {
// Here's the magic. Set up `require.ensure` to tell Webpack// to split here and load our search index dynamically.//// The first parameter defines possible dependencies that// must be loaded first. Given there aren't any, we will// leave it as an empty array.returnnewPromise(function (resolve, reject) {
try {
__webpack_require__.e/* nsure */(1, function (require) {
var lunr = __webpack_require__(155);
var search = __webpack_require__(156);
resolve({
index: lunr.Index.load(search.index),
lines: search.lines
});
});
} catch (err) {
reject(err);
}
});
}
/***/ }
So you can see my require.ensure gets transformed to __webpack_require__.e thanks to webpack. The more interesting bit is that particular function covered next:
manifest.b3f1586f30f110bf84e4.js
/******/// This file contains only the entry chunk./******/// The chunk loading function for additional chunks/******/ __webpack_require__.e = functionrequireEnsure(chunkId, callback) {
/******/// "0" is the signal for "already loaded"/******/if(installedChunks[chunkId] === 0)
/******/return callback.call(null, __webpack_require__);
/******/// an array means "currently loading"./******/if(installedChunks[chunkId] !== undefined) {
/******/ installedChunks[chunkId].push(callback);
/******/ } else {
/******/// start chunk loading/******/ installedChunks[chunkId] = [callback];
/******/var head = document.getElementsByTagName('head')[0];
/******/var script = document.createElement('script');
/******/ script.type = 'text/javascript';
/******/ script.charset = 'utf-8';
/******/ script.async = true;
/******/ script.src = __webpack_require__.p + "" + {"0":"ff56587996e597e4d868","1":"ec12fe80f7b40165d2fe","2":"cd47c1bfb8874d4b4dfb","3":"8d8a74ddd195dd94bec2"}[chunkId] + ".js";
/******/ head.appendChild(script);
/******/ }
/******/ };
This is where the magic happens. When we call this particular function, it injects a script to the page and loads the file. The file itself executes webpackJsonp([1,4],{ ... }) which allows it to associate with the application and eventually gives us the behavior what we want.
webpack 2 improves the situation further by providing System.import. Even though it's not entirely comparable, it gives us a Promise based interface and most importantly error handling.
Great @bebraw thanks for the write up, i read your blog as well on survivejs very well explained the only place i was stuck was how does the script that is dynamically loaded gets executed, does webpack inject a script tag and execute the script, and this line from your response above answers the question "When we call this particular function, it injects a script to the page and loads the file", and the example code with comments. Lastly i have doubt as to how the scope is maintained between the chunks??
Hi @pramodvidyarthi,
webpack writes code that injects a script tag, yeah. The scope is managed at the manifest file by the bootstrapping logic.
Check out the example in detail and walk through the code carefully. The bootstrapping process will make more sense then.
You can reach me through Gitter if you have more specific questions.
Juho Vepsäläinen
SurviveJS
It's easier to understand what it does by looking at the code it generates. I disabled minification at my lunr-demo and this is what I got:
app.ff56587996e597e4d868.js
function loadIndex() { // Here's the magic. Set up `require.ensure` to tell Webpack // to split here and load our search index dynamically. // // The first parameter defines possible dependencies that // must be loaded first. Given there aren't any, we will // leave it as an empty array. return new Promise(function (resolve, reject) { try { __webpack_require__.e/* nsure */(1, function (require) { var lunr = __webpack_require__(155); var search = __webpack_require__(156); resolve({ index: lunr.Index.load(search.index), lines: search.lines }); }); } catch (err) { reject(err); } }); } /***/ }So you can see my
require.ensuregets transformed to__webpack_require__.ethanks to webpack. The more interesting bit is that particular function covered next:manifest.b3f1586f30f110bf84e4.js
/******/ // This file contains only the entry chunk. /******/ // The chunk loading function for additional chunks /******/ __webpack_require__.e = function requireEnsure(chunkId, callback) { /******/ // "0" is the signal for "already loaded" /******/ if(installedChunks[chunkId] === 0) /******/ return callback.call(null, __webpack_require__); /******/ // an array means "currently loading". /******/ if(installedChunks[chunkId] !== undefined) { /******/ installedChunks[chunkId].push(callback); /******/ } else { /******/ // start chunk loading /******/ installedChunks[chunkId] = [callback]; /******/ var head = document.getElementsByTagName('head')[0]; /******/ var script = document.createElement('script'); /******/ script.type = 'text/javascript'; /******/ script.charset = 'utf-8'; /******/ script.async = true; /******/ script.src = __webpack_require__.p + "" + {"0":"ff56587996e597e4d868","1":"ec12fe80f7b40165d2fe","2":"cd47c1bfb8874d4b4dfb","3":"8d8a74ddd195dd94bec2"}[chunkId] + ".js"; /******/ head.appendChild(script); /******/ } /******/ };This is where the magic happens. When we call this particular function, it injects a script to the page and loads the file. The file itself executes
webpackJsonp([1,4],{ ... })which allows it to associate with the application and eventually gives us the behavior what we want.webpack 2 improves the situation further by providing
System.import. Even though it's not entirely comparable, it gives us aPromisebased interface and most importantly error handling.