From a72dfc0b62aa9817f6d0d1ad1af16b2aaac4bae1 Mon Sep 17 00:00:00 2001 From: Julian Scheid Date: Thu, 5 Nov 2020 11:50:25 +1300 Subject: [PATCH] Fix bug with named chunks in Webpack 5 Closes #135 --- examples/dynamic-modified/test.js | 2 +- examples/dynamic-named-chunks/README.md | 4 ++ examples/dynamic-named-chunks/chunk.js | 1 + examples/dynamic-named-chunks/index.js | 38 +++++++++++++++++++ examples/dynamic-named-chunks/test.js | 8 ++++ .../dynamic-named-chunks/webpack.config.js | 21 ++++++++++ jmtp.js | 2 +- 7 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 examples/dynamic-named-chunks/README.md create mode 100644 examples/dynamic-named-chunks/chunk.js create mode 100644 examples/dynamic-named-chunks/index.js create mode 100644 examples/dynamic-named-chunks/test.js create mode 100644 examples/dynamic-named-chunks/webpack.config.js diff --git a/examples/dynamic-modified/test.js b/examples/dynamic-modified/test.js index 70b5fe7..05734ca 100644 --- a/examples/dynamic-modified/test.js +++ b/examples/dynamic-modified/test.js @@ -12,7 +12,7 @@ module.exports.skip = function skip() { module.exports.check = function check(stats, url, browser) { const otherAsset = Object.keys(stats.compilation.assets).find(key => key !== 'index.js' && key.endsWith(".js")); - fs.writeFileSync('dist/' + otherAsset, 'xxx'); + fs.writeFileSync('dist/' + otherAsset, 'console.log("corrupted");'); return defaultCheck(stats, url, browser); }; diff --git a/examples/dynamic-named-chunks/README.md b/examples/dynamic-named-chunks/README.md new file mode 100644 index 0000000..f4d6101 --- /dev/null +++ b/examples/dynamic-named-chunks/README.md @@ -0,0 +1,4 @@ +# With a dynamically loaded, named chunk #hwp + +Ensure that when a named chunk is loaded dynamically with Webpack 5, +it receives a SRI hash. diff --git a/examples/dynamic-named-chunks/chunk.js b/examples/dynamic-named-chunks/chunk.js new file mode 100644 index 0000000..092bc2b --- /dev/null +++ b/examples/dynamic-named-chunks/chunk.js @@ -0,0 +1 @@ +; diff --git a/examples/dynamic-named-chunks/index.js b/examples/dynamic-named-chunks/index.js new file mode 100644 index 0000000..f5b2032 --- /dev/null +++ b/examples/dynamic-named-chunks/index.js @@ -0,0 +1,38 @@ +let scriptsWithIntegrity = []; + +const observer = new MutationObserver(mutationsList => { + Array.from(mutationsList).forEach(mutation => { + Array.from(mutation.addedNodes || []).forEach(node => { + if (node.nodeName === 'SCRIPT') { + if ( + node.getAttribute('crossOrigin') === 'anonymous' && + node + .getAttribute('integrity') + .match(/^sha256-[-A-Za-z0-9+/=]{44} sha384-[-A-Za-z0-9+/=]{64}$/) + ) { + scriptsWithIntegrity.push(node); + } + } + }); + }); +}); + +observer.observe(document.querySelector('head'), { childList: true }); + +import('./chunk') + .then(() => { + if ( + scriptsWithIntegrity.some( + script => + new URL(script.getAttribute('src')).pathname === '/chunk_js.js' + ) + ) { + console.log('ok'); + } else { + console.log('error'); + } + }) + .catch(e => { + console.error(e); + console.log('error'); + }); diff --git a/examples/dynamic-named-chunks/test.js b/examples/dynamic-named-chunks/test.js new file mode 100644 index 0000000..6ff4633 --- /dev/null +++ b/examples/dynamic-named-chunks/test.js @@ -0,0 +1,8 @@ +var webpackVersionComponents = require('webpack/package.json').version.split( + '.' +); +var webpackVersionMajor = Number(webpackVersionComponents[0]); + +module.exports.skip = function skip() { + return webpackVersionMajor < 5; +}; diff --git a/examples/dynamic-named-chunks/webpack.config.js b/examples/dynamic-named-chunks/webpack.config.js new file mode 100644 index 0000000..d5a07bf --- /dev/null +++ b/examples/dynamic-named-chunks/webpack.config.js @@ -0,0 +1,21 @@ +var SriPlugin = require('webpack-subresource-integrity'); +var HtmlWebpackPlugin = require('html-webpack-plugin'); + +module.exports = { + entry: { + index: './index.js' + }, + output: { + crossOriginLoading: 'anonymous', + }, + optimization: { + chunkIds: 'named', + }, + plugins: [ + new SriPlugin({ + hashFuncNames: ['sha256', 'sha384'], + enabled: true + }), + new HtmlWebpackPlugin() + ] +}; diff --git a/jmtp.js b/jmtp.js index bb51071..3a5b4b4 100644 --- a/jmtp.js +++ b/jmtp.js @@ -63,7 +63,7 @@ WebIntegrityJsonpMainTemplatePlugin.prototype.addAttribute = return (Template.asString || mainTemplate.asString)([ source, elName + '.integrity = __webpack_require__.sriHashes[' + - ((webpackVersionMajor >= 5 && elName === 'script') ? 'key.match(/^chunk-([0-9]+)$/)[1]' : 'chunkId') + + ((webpackVersionMajor >= 5 && elName === 'script') ? 'key.match(/^chunk-(.+)$/)[1]' : 'chunkId') + '];', elName + '.crossOrigin = ' + JSON.stringify(outputOptions.crossOriginLoading) + ';', ]);