Created
January 4, 2021 21:48
-
-
Save andreasvirkus/5cc3454422a351d655bc865e62fec836 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
const prettier = require("prettier"); | |
const pluginName = "HandleChunkLoadFailurePlugin"; | |
/** | |
* This Webpack plugin calls `window._chunkHandler.handleVersionChange()` when loading a chunk fails | |
*/ | |
class HandleChunkLoadFailurePlugin { | |
constructor(options = {}) { | |
this.options = Object.assign({}, options); | |
} | |
apply(compiler) { | |
compiler.hooks.compilation.tap(pluginName, (compilation) => { | |
const { mainTemplate } = compilation; | |
if (mainTemplate.hooks.jsonpScript) { | |
// Adapted from https://github.com/webpack/webpack/blob/11e94dd2d0a8d8baae75e715ff8a69f27a9e3014/lib/web/JsonpMainTemplatePlugin.js#L145-L210 | |
// https://github.com/webpack/webpack/issues/9611#issuecomment-523850870 | |
mainTemplate.hooks.jsonpScript.tap(pluginName, (source, chunk) => { | |
const { crossOriginLoading, chunkLoadTimeout, jsonpScriptType } = mainTemplate.outputOptions; | |
const crossOriginScript = ` | |
if (script.src.indexOf(window.location.origin + '/') !== 0) { | |
script.crossOrigin = ${JSON.stringify(crossOriginLoading)}; | |
} | |
`; | |
const scriptWithRetry = ` | |
// create error before stack unwound to get useful stacktrace later | |
var error = new Error(); | |
function loadScript(src) { | |
var script = document.createElement('script'); | |
var onScriptComplete; | |
${jsonpScriptType ? `script.type = ${JSON.stringify(jsonpScriptType)};` : ""} | |
script.charset = 'utf-8'; | |
script.timeout = ${chunkLoadTimeout / 1000}; | |
if (${mainTemplate.requireFn}.nc) { | |
script.setAttribute("nonce", ${mainTemplate.requireFn}.nc); | |
} | |
script.src = src; | |
${crossOriginLoading ? crossOriginScript : ""} | |
onScriptComplete = function (event) { | |
var chunk = installedChunks[chunkId]; | |
if (chunk) window._chunkHandler.handleVersionChange() | |
}; | |
script.onerror = onScriptComplete; | |
return script; | |
} | |
var script = loadScript(jsonpScriptSrc(chunkId)); | |
`; | |
const currentChunkName = chunk.name; | |
const addRetryCode = !this.options.chunks || this.options.chunks.includes(currentChunkName); | |
const script = addRetryCode ? scriptWithRetry : source; | |
return prettier.format(script, { | |
singleQuote: true, | |
parser: "babel", | |
}); | |
}); | |
} | |
}); | |
} | |
} | |
module.exports[pluginName] = HandleChunkLoadFailurePlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment