From 906450fedb042b3f08b559d17c4a125d9036b214 Mon Sep 17 00:00:00 2001 From: Remi Gebski Date: Sat, 28 Mar 2020 11:59:35 +0100 Subject: [PATCH] feat: add option `inject` --- README.md | 15 ++++++++++- src/index.js | 10 +++++++ test.js | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4645c051..ea7eac3b 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ look like: - + Webpack App @@ -149,6 +149,19 @@ An example of this is included in the repository. Currently only supports script tags. +### `inject` + +Type: `boolean | function`, default: `true` + +Inject conditionally. + +This option accepts arguments of different types: + +- boolean `false`: disables injection `true`: enables injection (defaults) +- function any predicate that takes an instance of html-webpack-plugin and + returns either `true` or `false` to control the injection of html metadata for + the html files generated by this instance. + ## Examples When adding assets, it's added to the start of the array, so when diff --git a/src/index.js b/src/index.js index 1680e230..a912f6e3 100644 --- a/src/index.js +++ b/src/index.js @@ -85,6 +85,7 @@ export default class AddAssetHtmlPlugin { publicPath, outputPath, files = [], + inject = true, }, ) { if (!filepath) { @@ -95,6 +96,15 @@ export default class AddAssetHtmlPlugin { const fileFilters = Array.isArray(files) ? files : [files]; + const shouldInject = + typeof inject === 'function' + ? inject(htmlPluginData.plugin) + : Boolean(inject); + + if (!shouldInject) { + return; + } + if (fileFilters.length > 0) { const shouldSkip = !fileFilters.some(file => micromatch.isMatch(htmlPluginData.outputName, file), diff --git a/test.js b/test.js index 3184cdf9..119e4c99 100644 --- a/test.js +++ b/test.js @@ -286,3 +286,79 @@ test('filepath without globbyMagic should just return', async () => { const ret = await handleUrl(assets); expect(ret).toHaveLength(1); }); + +describe('inject assets conditionally', () => { + test('does not inject if false', async () => { + const compilation = { options: { output: { publicPath: 'vendor/' } } }; + const pluginData = Object.assign( + { assets: { js: [], css: [] } }, + pluginMock, + ); + const plugin = new AddAssetHtmlPlugin({ + filepath: path.join(__dirname, 'my-file.js'), + inject: false, + }); + + await plugin.addAllAssetsToCompilation(compilation, pluginData); + + expect(pluginData.assets.js).toHaveLength(0); + }); + + test('if inject is a callback it gets called with the HtmlPlugin data', async () => { + const mock = { + plugin: { + options: { + HTML_PLUGIN_OPTION: 'hello', + }, + }, + }; + + const compilation = { options: { output: { publicPath: 'vendor/' } } }; + const pluginData = Object.assign({ assets: { js: [], css: [] } }, mock); + const injectCallback = jest.fn(); + const plugin = new AddAssetHtmlPlugin({ + filepath: path.join(__dirname, 'my-file.js'), + inject: injectCallback, + }); + + await plugin.addAllAssetsToCompilation(compilation, pluginData); + + expect(injectCallback).toHaveBeenCalledWith(mock.plugin); + }); + + test('does not inject if the callback returns false', async () => { + const compilation = { options: { output: { publicPath: 'vendor/' } } }; + const pluginData = Object.assign( + { assets: { js: [], css: [] } }, + pluginMock, + ); + const plugin = new AddAssetHtmlPlugin({ + filepath: path.join(__dirname, 'my-file.js'), + inject: () => { + return false; + }, + }); + + await plugin.addAllAssetsToCompilation(compilation, pluginData); + + expect(pluginData.assets.js).toHaveLength(0); + }); + + test('injects if the callback returns true', async () => { + const compilation = { options: { output: { publicPath: 'vendor/' } } }; + const pluginData = Object.assign( + { assets: { js: [], css: [] } }, + pluginMock, + ); + const plugin = new AddAssetHtmlPlugin({ + filepath: path.join(__dirname, 'my-file.js'), + inject: () => { + return true; + }, + }); + + await plugin.addAllAssetsToCompilation(compilation, pluginData); + + expect(pluginData.assets.js).toHaveLength(1); + }); +});