Skip to content

Commit 239e7b9

Browse files
SorsOpsicelam
andauthored
feat: support preserving inlined assets by regex (#434)
Co-authored-by: Ice Lam <[email protected]>
1 parent d9e94ff commit 239e7b9

File tree

7 files changed

+95
-2
lines changed

7 files changed

+95
-2
lines changed

__tests__/HtmlInlineScriptPlugin.test.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import webpack from 'webpack';
55
import Self from '../dist';
66

77
import simpleConfig from './cases/simple/webpack.config';
8+
import preserveConfig from './cases/preserveAsset/webpack.config';
89
import multipleInstanceConfig from './cases/multiple-instance/webpack.config';
910
import jsWithImportConfig from './cases/js-with-import/webpack.config';
1011
import webWorkerConfig from './cases/web-worker/webpack.config';
@@ -48,6 +49,40 @@ describe('HtmlInlineScriptPlugin', () => {
4849
await webpackPromise;
4950
});
5051

52+
it('should preserve the output of an asset if requested', async () => {
53+
const webpackPromise = new Promise((resolve) => {
54+
const compiler = webpack(preserveConfig);
55+
console.log(preserveConfig)
56+
57+
compiler.run((error, stats) => {
58+
expect(error).toBeNull();
59+
60+
const statsErrors = stats?.compilation.errors;
61+
expect(statsErrors?.length).toBe(0);
62+
63+
const result = fs.readFileSync(
64+
path.join(__dirname, 'cases/preserveAsset/dist/index.html'),
65+
'utf8',
66+
);
67+
68+
const expected = fs.readFileSync(
69+
path.join(__dirname, 'cases/preserveAsset/expected/index.html'),
70+
'utf8',
71+
);
72+
expect(result).toBe(expected);
73+
74+
const expectedFileList = fs.readdirSync(path.join(__dirname, 'cases/preserveAsset/expected/'));
75+
const generatedFileList = fs.readdirSync(path.join(__dirname, 'cases/preserveAsset/dist/'));
76+
expect(expectedFileList.sort()).toEqual(generatedFileList.sort());
77+
78+
resolve(true);
79+
});
80+
});
81+
82+
await webpackPromise;
83+
});
84+
85+
5186
it('should build webpack config having multiple HTML webpack plugin instance without error', async () => {
5287
const webpackPromise = new Promise((resolve) => {
5388
const compiler = webpack(multipleInstanceConfig);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta name="language" content="English"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="minimum-scale=1,initial-scale=1,width=device-width,shrink-to-fit=no"/><title>webpack test</title><script defer="defer">console.log("Hello world");</script></head><body><p>This is minimal code to demonstrate webpack usage</p></body></html>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
console.log("Hello world");
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
6+
<meta name="language" content="English" />
7+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
8+
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no" />
9+
<title>webpack test</title>
10+
</head>
11+
<body>
12+
<p>This is minimal code to demonstrate webpack usage</p>
13+
</body>
14+
</html>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// eslint-disable-next-line no-console
2+
console.log('Hello world');
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import path from 'path';
2+
import type { Configuration } from 'webpack';
3+
import HtmlWebpackPlugin from 'html-webpack-plugin';
4+
import Self from '../../../dist';
5+
6+
const config: Configuration = {
7+
mode: 'production',
8+
entry: {
9+
ui: path.join(__dirname, './fixtures/index.js')
10+
},
11+
output: {
12+
path: path.join(__dirname, './dist'),
13+
filename: '[name].js'
14+
},
15+
plugins: [
16+
new HtmlWebpackPlugin({
17+
chunks: ['ui'],
18+
template: path.resolve(__dirname, './fixtures/index.html')
19+
}),
20+
new Self({
21+
assetPreservePattern: [/^ui[.]js$/]
22+
})
23+
]
24+
};
25+
26+
export default config;

src/HtmlInlineScriptPlugin.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { PLUGIN_PREFIX } from './constants';
77
export type PluginOptions = {
88
scriptMatchPattern?: RegExp[];
99
htmlMatchPattern?: RegExp[];
10+
assetPreservePattern?: RegExp[];
1011
};
1112

1213
class HtmlInlineScriptPlugin implements WebpackPluginInstance {
@@ -18,6 +19,8 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
1819

1920
ignoredHtmlFiles: string[];
2021

22+
assetPreservePattern: NonNullable<PluginOptions['assetPreservePattern']>;
23+
2124
constructor(options: PluginOptions = {}) {
2225
if (options && Array.isArray(options)) {
2326
// eslint-disable-next-line no-console
@@ -33,12 +36,14 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
3336

3437
const {
3538
scriptMatchPattern = [/.+[.]js$/],
36-
htmlMatchPattern = [/.+[.]html$/]
39+
htmlMatchPattern = [/.+[.]html$/],
40+
assetPreservePattern = [],
3741
} = options;
3842

3943
this.scriptMatchPattern = scriptMatchPattern;
4044
this.htmlMatchPattern = htmlMatchPattern;
4145
this.processedScriptFiles = [];
46+
this.assetPreservePattern = assetPreservePattern;
4247
this.ignoredHtmlFiles = [];
4348
}
4449

@@ -48,6 +53,13 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
4853
return this.scriptMatchPattern.some((test) => assetName.match(test));
4954
}
5055

56+
isFileNeedsToBePreserved(
57+
assetName: string
58+
): boolean {
59+
return this.assetPreservePattern.some((test) => assetName.match(test));
60+
}
61+
62+
5163
shouldProcessHtml(
5264
templateName: string
5365
): boolean {
@@ -120,7 +132,9 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
120132
}, (assets) => {
121133
if (this.ignoredHtmlFiles.length === 0) {
122134
this.processedScriptFiles.forEach((assetName) => {
123-
delete assets[assetName];
135+
if (!this.isFileNeedsToBePreserved(assetName)) {
136+
delete assets[assetName];
137+
}
124138
});
125139
}
126140
});

0 commit comments

Comments
 (0)