From 9ce669df4d1bc66eca98cfe30163bc944a8c9648 Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 26 Mar 2021 18:17:49 +0800 Subject: [PATCH 1/3] wrap into dom loaded event listener if defer is specified --- packages/react-dev-utils/InlineChunkHtmlPlugin.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/react-dev-utils/InlineChunkHtmlPlugin.js b/packages/react-dev-utils/InlineChunkHtmlPlugin.js index df427afadd..d07ecc48b6 100644 --- a/packages/react-dev-utils/InlineChunkHtmlPlugin.js +++ b/packages/react-dev-utils/InlineChunkHtmlPlugin.js @@ -27,7 +27,11 @@ class InlineChunkHtmlPlugin { if (asset == null) { return tag; } - return { tagName: 'script', innerHTML: asset.source(), closeTag: true }; + let source = asset.source(); + if (tag.attributes.defer) { + source = `window.addEventListener('DOMContentLoaded', function () { ${source} })`; + } + return { tagName: 'script', innerHTML: source, closeTag: true }; } apply(compiler) { From 0c85e45709a1faf5546298d36d9229f265db8dcd Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 26 Mar 2021 18:45:22 +0800 Subject: [PATCH 2/3] Append to body rather than event listener --- .../react-dev-utils/InlineChunkHtmlPlugin.js | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/react-dev-utils/InlineChunkHtmlPlugin.js b/packages/react-dev-utils/InlineChunkHtmlPlugin.js index d07ecc48b6..d968358849 100644 --- a/packages/react-dev-utils/InlineChunkHtmlPlugin.js +++ b/packages/react-dev-utils/InlineChunkHtmlPlugin.js @@ -27,11 +27,7 @@ class InlineChunkHtmlPlugin { if (asset == null) { return tag; } - let source = asset.source(); - if (tag.attributes.defer) { - source = `window.addEventListener('DOMContentLoaded', function () { ${source} })`; - } - return { tagName: 'script', innerHTML: source, closeTag: true }; + return { tagName: 'script', innerHTML: asset.source(), closeTag: true }; } apply(compiler) { @@ -41,13 +37,22 @@ class InlineChunkHtmlPlugin { } compiler.hooks.compilation.tap('InlineChunkHtmlPlugin', compilation => { - const tagFunction = tag => - this.getInlinedTag(publicPath, compilation.assets, tag); - const hooks = this.htmlWebpackPlugin.getHooks(compilation); hooks.alterAssetTagGroups.tap('InlineChunkHtmlPlugin', assets => { - assets.headTags = assets.headTags.map(tagFunction); - assets.bodyTags = assets.bodyTags.map(tagFunction); + const deferScripts = []; + const tagFunction = tag => { + const result = this.getInlinedTag(publicPath, compilation.assets, tag); + + if (tag.tagName !== 'script' || !(tag.attributes && tag.attributes.defer)) { + return result; + } + + deferScripts.push(result); + return undefined; + } + + assets.headTags = assets.headTags.map(tagFunction).filter(Boolean); + assets.bodyTags = assets.bodyTags.map(tagFunction).filter(Boolean).concat(deferScripts); }); // Still emit the runtime chunk for users who do not use our generated From 7b723f4c6b96abaa5fa2f174c0b2da4517d1d61b Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 26 Mar 2021 18:52:46 +0800 Subject: [PATCH 3/3] Avoid transform if not inlined --- packages/react-dev-utils/InlineChunkHtmlPlugin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react-dev-utils/InlineChunkHtmlPlugin.js b/packages/react-dev-utils/InlineChunkHtmlPlugin.js index d968358849..baac68d959 100644 --- a/packages/react-dev-utils/InlineChunkHtmlPlugin.js +++ b/packages/react-dev-utils/InlineChunkHtmlPlugin.js @@ -43,7 +43,7 @@ class InlineChunkHtmlPlugin { const tagFunction = tag => { const result = this.getInlinedTag(publicPath, compilation.assets, tag); - if (tag.tagName !== 'script' || !(tag.attributes && tag.attributes.defer)) { + if (result === tag || tag.tagName !== 'script' || !(tag.attributes && tag.attributes.defer)) { return result; }