From 9562affd2b6b20af65f4f8e866f9314759eebdd0 Mon Sep 17 00:00:00 2001 From: SorsOps <80043879+sorsOps@users.noreply.github.com> Date: Thu, 1 Jun 2023 21:20:50 +0200 Subject: [PATCH 1/3] Support preservation --- __tests__/HtmlInlineScriptPlugin.test.ts | 35 +++++++++++++++++++ .../cases/preserveAsset/expected/index.html | 1 + __tests__/cases/preserveAsset/expected/ui.js | 1 + .../cases/preserveAsset/fixtures/index.html | 14 ++++++++ .../cases/preserveAsset/fixtures/index.js | 2 ++ .../cases/preserveAsset/webpack.config.ts | 26 ++++++++++++++ src/HtmlInlineScriptPlugin.ts | 11 ++++-- 7 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 __tests__/cases/preserveAsset/expected/index.html create mode 100644 __tests__/cases/preserveAsset/expected/ui.js create mode 100644 __tests__/cases/preserveAsset/fixtures/index.html create mode 100644 __tests__/cases/preserveAsset/fixtures/index.js create mode 100644 __tests__/cases/preserveAsset/webpack.config.ts diff --git a/__tests__/HtmlInlineScriptPlugin.test.ts b/__tests__/HtmlInlineScriptPlugin.test.ts index 8306199..1596ead 100644 --- a/__tests__/HtmlInlineScriptPlugin.test.ts +++ b/__tests__/HtmlInlineScriptPlugin.test.ts @@ -5,6 +5,7 @@ import webpack from 'webpack'; import Self from '../dist'; import simpleConfig from './cases/simple/webpack.config'; +import preserveConfig from './cases/preserveAsset/webpack.config'; import multipleInstanceConfig from './cases/multiple-instance/webpack.config'; import jsWithImportConfig from './cases/js-with-import/webpack.config'; import webWorkerConfig from './cases/web-worker/webpack.config'; @@ -48,6 +49,40 @@ describe('HtmlInlineScriptPlugin', () => { await webpackPromise; }); + it('should preserve the output of an asset if requested', async () => { + const webpackPromise = new Promise((resolve) => { + const compiler = webpack(preserveConfig); + console.log(preserveConfig) + + compiler.run((error, stats) => { + expect(error).toBeNull(); + + const statsErrors = stats?.compilation.errors; + expect(statsErrors?.length).toBe(0); + + const result = fs.readFileSync( + path.join(__dirname, 'cases/preserveAsset/dist/index.html'), + 'utf8', + ); + + const expected = fs.readFileSync( + path.join(__dirname, 'cases/preserveAsset/expected/index.html'), + 'utf8', + ); + expect(result).toBe(expected); + + const expectedFileList = fs.readdirSync(path.join(__dirname, 'cases/preserveAsset/expected/')); + const generatedFileList = fs.readdirSync(path.join(__dirname, 'cases/preserveAsset/dist/')); + expect(expectedFileList.sort()).toEqual(generatedFileList.sort()); + + resolve(true); + }); + }); + + await webpackPromise; + }); + + it('should build webpack config having multiple HTML webpack plugin instance without error', async () => { const webpackPromise = new Promise((resolve) => { const compiler = webpack(multipleInstanceConfig); diff --git a/__tests__/cases/preserveAsset/expected/index.html b/__tests__/cases/preserveAsset/expected/index.html new file mode 100644 index 0000000..bbe46c3 --- /dev/null +++ b/__tests__/cases/preserveAsset/expected/index.html @@ -0,0 +1 @@ +webpack test

This is minimal code to demonstrate webpack usage

\ No newline at end of file diff --git a/__tests__/cases/preserveAsset/expected/ui.js b/__tests__/cases/preserveAsset/expected/ui.js new file mode 100644 index 0000000..592f786 --- /dev/null +++ b/__tests__/cases/preserveAsset/expected/ui.js @@ -0,0 +1 @@ +console.log("Hello world"); \ No newline at end of file diff --git a/__tests__/cases/preserveAsset/fixtures/index.html b/__tests__/cases/preserveAsset/fixtures/index.html new file mode 100644 index 0000000..c061c8e --- /dev/null +++ b/__tests__/cases/preserveAsset/fixtures/index.html @@ -0,0 +1,14 @@ + + + + + + + + + webpack test + + +

This is minimal code to demonstrate webpack usage

+ + diff --git a/__tests__/cases/preserveAsset/fixtures/index.js b/__tests__/cases/preserveAsset/fixtures/index.js new file mode 100644 index 0000000..2ce7e4a --- /dev/null +++ b/__tests__/cases/preserveAsset/fixtures/index.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line no-console +console.log('Hello world'); diff --git a/__tests__/cases/preserveAsset/webpack.config.ts b/__tests__/cases/preserveAsset/webpack.config.ts new file mode 100644 index 0000000..feda4b8 --- /dev/null +++ b/__tests__/cases/preserveAsset/webpack.config.ts @@ -0,0 +1,26 @@ +import path from 'path'; +import type { Configuration } from 'webpack'; +import HtmlWebpackPlugin from 'html-webpack-plugin'; +import Self from '../../../dist'; + +const config: Configuration = { + mode: 'production', + entry: { + ui: path.join(__dirname, './fixtures/index.js') + }, + output: { + path: path.join(__dirname, './dist'), + filename: '[name].js' + }, + plugins: [ + new HtmlWebpackPlugin({ + chunks: ['ui'], + template: path.resolve(__dirname, './fixtures/index.html') + }), + new Self({ + preserveAsset: (asset) => asset === 'ui.js' + }) + ] +}; + +export default config; diff --git a/src/HtmlInlineScriptPlugin.ts b/src/HtmlInlineScriptPlugin.ts index 4c64e3b..ba2c9af 100644 --- a/src/HtmlInlineScriptPlugin.ts +++ b/src/HtmlInlineScriptPlugin.ts @@ -7,6 +7,7 @@ import { PLUGIN_PREFIX } from './constants'; export type PluginOptions = { scriptMatchPattern?: RegExp[]; htmlMatchPattern?: RegExp[]; + preserveAsset?: (assetName: string) => boolean }; class HtmlInlineScriptPlugin implements WebpackPluginInstance { @@ -18,6 +19,8 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { ignoredHtmlFiles: string[]; + preserveAsset: (assetName: string) => boolean + constructor(options: PluginOptions = {}) { if (options && Array.isArray(options)) { // eslint-disable-next-line no-console @@ -33,12 +36,14 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { const { scriptMatchPattern = [/.+[.]js$/], - htmlMatchPattern = [/.+[.]html$/] + htmlMatchPattern = [/.+[.]html$/], + preserveAsset = () => false } = options; this.scriptMatchPattern = scriptMatchPattern; this.htmlMatchPattern = htmlMatchPattern; this.processedScriptFiles = []; + this.preserveAsset = preserveAsset; this.ignoredHtmlFiles = []; } @@ -120,7 +125,9 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { }, (assets) => { if (this.ignoredHtmlFiles.length === 0) { this.processedScriptFiles.forEach((assetName) => { - delete assets[assetName]; + if (!this.preserveAsset(assetName)) { + delete assets[assetName]; + } }); } }); From c74a9c83f83064a0c10d7c8961079921adfe9d0a Mon Sep 17 00:00:00 2001 From: SorsOps <80043879+sorsOps@users.noreply.github.com> Date: Fri, 2 Jun 2023 09:14:03 +0200 Subject: [PATCH 2/3] Convert to regexp --- __tests__/cases/preserveAsset/webpack.config.ts | 2 +- src/HtmlInlineScriptPlugin.ts | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/__tests__/cases/preserveAsset/webpack.config.ts b/__tests__/cases/preserveAsset/webpack.config.ts index feda4b8..efd150b 100644 --- a/__tests__/cases/preserveAsset/webpack.config.ts +++ b/__tests__/cases/preserveAsset/webpack.config.ts @@ -18,7 +18,7 @@ const config: Configuration = { template: path.resolve(__dirname, './fixtures/index.html') }), new Self({ - preserveAsset: (asset) => asset === 'ui.js' + preserveAsset: [/^ui[.]js$/] }) ] }; diff --git a/src/HtmlInlineScriptPlugin.ts b/src/HtmlInlineScriptPlugin.ts index ba2c9af..95303ad 100644 --- a/src/HtmlInlineScriptPlugin.ts +++ b/src/HtmlInlineScriptPlugin.ts @@ -7,7 +7,7 @@ import { PLUGIN_PREFIX } from './constants'; export type PluginOptions = { scriptMatchPattern?: RegExp[]; htmlMatchPattern?: RegExp[]; - preserveAsset?: (assetName: string) => boolean + preserveAsset?: RegExp[]; }; class HtmlInlineScriptPlugin implements WebpackPluginInstance { @@ -19,7 +19,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { ignoredHtmlFiles: string[]; - preserveAsset: (assetName: string) => boolean + preserveAsset: NonNullable; constructor(options: PluginOptions = {}) { if (options && Array.isArray(options)) { @@ -37,7 +37,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { const { scriptMatchPattern = [/.+[.]js$/], htmlMatchPattern = [/.+[.]html$/], - preserveAsset = () => false + preserveAsset = [], } = options; this.scriptMatchPattern = scriptMatchPattern; @@ -53,6 +53,13 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { return this.scriptMatchPattern.some((test) => assetName.match(test)); } + isFileNeedsToBePreserved( + assetName: string + ): boolean { + return this.preserveAsset.some((test) => assetName.match(test)); + } + + shouldProcessHtml( templateName: string ): boolean { @@ -125,7 +132,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { }, (assets) => { if (this.ignoredHtmlFiles.length === 0) { this.processedScriptFiles.forEach((assetName) => { - if (!this.preserveAsset(assetName)) { + if (!this.isFileNeedsToBePreserved(assetName)) { delete assets[assetName]; } }); From 9a229457cfd996fe4a9107fed4a0c01ed089e48e Mon Sep 17 00:00:00 2001 From: Ice Lam Date: Fri, 2 Jun 2023 22:56:45 +0800 Subject: [PATCH 3/3] refactor: rename preserveAsset to assetPreservePattern to sync with other variable name. --- __tests__/cases/preserveAsset/webpack.config.ts | 2 +- src/HtmlInlineScriptPlugin.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/__tests__/cases/preserveAsset/webpack.config.ts b/__tests__/cases/preserveAsset/webpack.config.ts index efd150b..9cd00b8 100644 --- a/__tests__/cases/preserveAsset/webpack.config.ts +++ b/__tests__/cases/preserveAsset/webpack.config.ts @@ -18,7 +18,7 @@ const config: Configuration = { template: path.resolve(__dirname, './fixtures/index.html') }), new Self({ - preserveAsset: [/^ui[.]js$/] + assetPreservePattern: [/^ui[.]js$/] }) ] }; diff --git a/src/HtmlInlineScriptPlugin.ts b/src/HtmlInlineScriptPlugin.ts index 95303ad..696bb33 100644 --- a/src/HtmlInlineScriptPlugin.ts +++ b/src/HtmlInlineScriptPlugin.ts @@ -7,7 +7,7 @@ import { PLUGIN_PREFIX } from './constants'; export type PluginOptions = { scriptMatchPattern?: RegExp[]; htmlMatchPattern?: RegExp[]; - preserveAsset?: RegExp[]; + assetPreservePattern?: RegExp[]; }; class HtmlInlineScriptPlugin implements WebpackPluginInstance { @@ -19,7 +19,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { ignoredHtmlFiles: string[]; - preserveAsset: NonNullable; + assetPreservePattern: NonNullable; constructor(options: PluginOptions = {}) { if (options && Array.isArray(options)) { @@ -37,13 +37,13 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { const { scriptMatchPattern = [/.+[.]js$/], htmlMatchPattern = [/.+[.]html$/], - preserveAsset = [], + assetPreservePattern = [], } = options; this.scriptMatchPattern = scriptMatchPattern; this.htmlMatchPattern = htmlMatchPattern; this.processedScriptFiles = []; - this.preserveAsset = preserveAsset; + this.assetPreservePattern = assetPreservePattern; this.ignoredHtmlFiles = []; } @@ -56,7 +56,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance { isFileNeedsToBePreserved( assetName: string ): boolean { - return this.preserveAsset.some((test) => assetName.match(test)); + return this.assetPreservePattern.some((test) => assetName.match(test)); }