From ec538ab9827b7ece6a49a8de06d59ff8bbd5502d Mon Sep 17 00:00:00 2001 From: Robert Main Date: Fri, 16 Apr 2021 22:52:51 -0400 Subject: [PATCH 1/4] Plugin allows you to inject a custom root element --- index.js | 20 +++++++++++++++++++- spec/basic.spec.js | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 45f286ad..35a46a9a 100644 --- a/index.js +++ b/index.js @@ -62,7 +62,8 @@ class HtmlWebpackPlugin { meta: {}, base: false, title: 'Webpack App', - xhtml: false + xhtml: false, + rootElement: false }; /** @type {ProcessedHtmlWebpackOptions} */ @@ -82,6 +83,11 @@ class HtmlWebpackPlugin { options.meta = Object.assign({}, options.meta, defaultMeta, userOptions.meta); } + // Only adds the root element if it was set + if (options.rootElement) { + options.rootElement = userOptions.rootElement; + } + // entryName to fileName conversion function const userOptionFilename = userOptions.filename || defaultOptions.filename; const filenameFunction = typeof userOptionFilename === 'function' @@ -298,6 +304,18 @@ function hookIntoCompiler (compiler, options, plugin) { (options.inject !== 'body' && options.scriptLoading !== 'blocking') ? 'head' : 'body'; // Group assets to `head` and `body` tag arrays const assetGroups = generateAssetGroups(assetTags, scriptTarget); + + if (options.rootElement) { + assetGroups.bodyTags.push({ + tagName: options.rootElement.tag, + voidTag: false, + attributes: { + id: options.rootElement.id + }, + meta: {} + }); + } + // Allow third-party-plugin authors to reorder and change the assetTags once they are grouped return getHtmlWebpackPluginHooks(compilation).alterAssetTagGroups.promise({ headTags: assetGroups.headTags, diff --git a/spec/basic.spec.js b/spec/basic.spec.js index 794e14c6..6995a921 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -2799,4 +2799,23 @@ describe('HtmlWebpackPlugin', () => { done(); }); }); + it('allows you to inject a custom root element', done => { + testHtmlPlugin({ + mode: 'none', + entry: { + app: path.join(__dirname, 'fixtures/index.js') + }, + output: { + path: OUTPUT_DIR, + filename: '[name]_bundle.js' + }, + plugins: [new HtmlWebpackPlugin({ + template: path.join(__dirname, 'fixtures/plain.html'), + rootElement: { + tag: 'div', + id: 'app' + } + })] + }, ['
'], null, done); + }); }); From 40d9dbf62e47c72f9b716824e714d4702915de1f Mon Sep 17 00:00:00 2001 From: Robert Main Date: Sat, 17 Apr 2021 00:06:22 -0400 Subject: [PATCH 2/4] Add default fallback values for both options --- index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 35a46a9a..44b76178 100644 --- a/index.js +++ b/index.js @@ -307,10 +307,10 @@ function hookIntoCompiler (compiler, options, plugin) { if (options.rootElement) { assetGroups.bodyTags.push({ - tagName: options.rootElement.tag, + tagName: options.rootElement.tag || 'div', voidTag: false, attributes: { - id: options.rootElement.id + id: options.rootElement.id || 'root' }, meta: {} }); From 4034fbba46ca632d0ef4a8cf85050903b54be0a2 Mon Sep 17 00:00:00 2001 From: Robert Main Date: Sat, 17 Apr 2021 00:11:15 -0400 Subject: [PATCH 3/4] Remove unused template option --- spec/basic.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/basic.spec.js b/spec/basic.spec.js index 6995a921..ac6434ba 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -2810,7 +2810,6 @@ describe('HtmlWebpackPlugin', () => { filename: '[name]_bundle.js' }, plugins: [new HtmlWebpackPlugin({ - template: path.join(__dirname, 'fixtures/plain.html'), rootElement: { tag: 'div', id: 'app' From 5c7037a1878d329fe1e86a0c50f4371404cb5790 Mon Sep 17 00:00:00 2001 From: Robert Main Date: Sat, 17 Apr 2021 00:24:15 -0400 Subject: [PATCH 4/4] Add tests to cover default values for rootElement --- spec/basic.spec.js | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/spec/basic.spec.js b/spec/basic.spec.js index ac6434ba..373a4a43 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -2811,10 +2811,44 @@ describe('HtmlWebpackPlugin', () => { }, plugins: [new HtmlWebpackPlugin({ rootElement: { - tag: 'div', + tag: 'main', + id: 'app' + } + })] + }, ['
'], null, done); + }); + it('provides a default tag', done => { + testHtmlPlugin({ + mode: 'none', + entry: { + app: path.join(__dirname, 'fixtures/index.js') + }, + output: { + path: OUTPUT_DIR, + filename: '[name]_bundle.js' + }, + plugins: [new HtmlWebpackPlugin({ + rootElement: { id: 'app' } })] }, ['
'], null, done); }); + it('provides a default id', done => { + testHtmlPlugin({ + mode: 'none', + entry: { + app: path.join(__dirname, 'fixtures/index.js') + }, + output: { + path: OUTPUT_DIR, + filename: '[name]_bundle.js' + }, + plugins: [new HtmlWebpackPlugin({ + rootElement: { + tag: 'div' + } + })] + }, ['
'], null, done); + }); });