Skip to content

Instantly share code, notes, and snippets.

@willwillems
Last active June 8, 2024 21:36
Show Gist options
  • Save willwillems/b792d415ba4487163e7063fe7953813d to your computer and use it in GitHub Desktop.
Save willwillems/b792d415ba4487163e7063fe7953813d to your computer and use it in GitHub Desktop.
Custom webpack chunk loading from a web extension (Chrome) content script.
// Throw this in your background script, it injects a generated webpack chunk when asked
chrome.runtime.onMessage.addListener(function ({ type, data}, sender, sendResponse) {
if (type === 'requestFileInjection') {
const file = data.fileName
if (!file) throw new Error('No file name provided.')
chrome.tabs.executeScript({ file: `${file}.js` }, (result) => {
console.log(`${file}.js injected`)
return sendResponse({ type: 'injected', target: { src: `${file}.js` }, success: true })
})
return true // return true so sendResponse stays valid
}
})
// Import at the top of your entry file, it requests an injection from the background script.
var installedChunks = {
"page": 0
};
__webpack_require__.e = function requireEnsure(chunkId) {
var promises = [];
// JSONP chunk loading for javascript
var installedChunkData = installedChunks[chunkId];
if (installedChunkData !== 0) { // 0 means "already installed".
// a Promise means "currently loading".
if (installedChunkData) {
promises.push(installedChunkData[2]);
} else {
// setup Promise in chunk cache
var promise = new Promise(function (resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
promises.push(installedChunkData[2] = promise);
// create error before stack unwound to get useful stacktrace later
var error = new Error();
onScriptComplete = function (event) {
// if type is injected & success set chunk to loaded and resolve promise
if (event && event.type === 'injected' && event.success === true) { installedChunks[chunkId][0](); installedChunks[chunkId] = 0 };
// avoid mem leaks in IE.
window.clearTimeout(timeout);
var chunk = installedChunks[chunkId];
if (chunk !== 0) {
if (chunk) {
var errorType = event && (event.type === 'load' ? 'missing' : event.type);
var realSrc = event && event.target && event.target.src;
error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
error.name = 'ChunkLoadError';
error.type = errorType;
error.request = realSrc;
chunk[1](error);
}
installedChunks[chunkId] = undefined;
}
};
var timeout = setTimeout(function () {
onScriptComplete({
type: 'timeout'
});
}, 120000);
// start chunk loading
chrome.runtime.sendMessage({ type: "requestFileInjection", data: { fileName: chunkId } }, onScriptComplete)
}
}
return Promise.all(promises);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment