Last active
June 8, 2024 21:36
-
-
Save willwillems/b792d415ba4487163e7063fe7953813d to your computer and use it in GitHub Desktop.
Custom webpack chunk loading from a web extension (Chrome) content script.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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