Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c333304

Browse files
committed
fix: resolve public path base on html-webpack-plugin and webpack config
1 parent cea06cd commit c333304

File tree

7 files changed

+115
-8
lines changed

7 files changed

+115
-8
lines changed

‎.eslintrc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@
3232
}],
3333
"import/extensions": ["error", {
3434
"js": "never",
35-
"ts": "never",
36-
}]
35+
"ts": "never"
36+
}],
37+
"class-methods-use-this": "off"
3738
},
3839
"overrides": [
3940
{
@@ -51,15 +52,15 @@
5152
"airbnb-base",
5253
"plugin:jest/recommended",
5354
"plugin:@typescript-eslint/eslint-recommended",
54-
"plugin:@typescript-eslint/recommended",
55+
"plugin:@typescript-eslint/recommended"
5556
],
5657
"env": { "node": true },
5758
"rules": {
5859
"@typescript-eslint/no-var-requires": ["off"],
5960
"no-console": ["off"],
6061
"import/extensions": ["error", {
6162
"js": "never",
62-
"ts": "never",
63+
"ts": "never"
6364
}]
6465
}
6566
}

‎__tests__/HtmlInlineScriptPlugin.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import ignoreHtmlsConfig from './cases/ignore-htmls/webpack.config';
1414
import ignoreScriptsAndHtmlsConfig from './cases/ignore-scripts-and-htmls/webpack.config';
1515
import filenameWithSpecialCharactersConfig from './cases/filename-with-special-characters/webpack.config';
1616
import escapeScriptTagEndConfig from './cases/escape-script-end-tag/webpack.config';
17+
import htmlInsideSubfolderConfig from './cases/html-inside-subfolder/webpack.config';
1718

1819
describe('HtmlInlineScriptPlugin', () => {
1920
it('should build simple webpack config without error', async () => {
@@ -205,6 +206,42 @@ describe('HtmlInlineScriptPlugin', () => {
205206
await webpackPromise;
206207
});
207208

209+
it('should build webpack config that outputs html file inside subfolder without error', async () => {
210+
const webpackPromise = new Promise((resolve) => {
211+
const compiler = webpack(htmlInsideSubfolderConfig);
212+
213+
compiler.run((error, stats) => {
214+
expect(error).toBeNull();
215+
216+
const statsErrors = stats?.compilation.errors;
217+
expect(statsErrors?.length).toBe(0);
218+
219+
const result = fs.readFileSync(
220+
path.join(__dirname, 'cases/html-inside-subfolder/dist/frontend/index.html'),
221+
'utf8',
222+
);
223+
224+
const expected = fs.readFileSync(
225+
path.join(__dirname, 'cases/html-inside-subfolder/expected/frontend/index.html'),
226+
'utf8',
227+
);
228+
expect(result).toBe(expected);
229+
230+
const expectedParentFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/expected/'));
231+
const generatedParentFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/dist/'));
232+
expect(expectedParentFileList.sort()).toEqual(generatedParentFileList.sort());
233+
234+
const expectedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/expected/'));
235+
const generatedChildFileList = fs.readdirSync(path.join(__dirname, 'cases/html-inside-subfolder/dist/'));
236+
expect(expectedChildFileList.sort()).toEqual(generatedChildFileList.sort());
237+
238+
resolve(true);
239+
});
240+
});
241+
242+
await webpackPromise;
243+
});
244+
208245
it('should inline filename with spacial characters without error', async () => {
209246
const webpackPromise = new Promise((resolve) => {
210247
const compiler = webpack(filenameWithSpecialCharactersConfig);
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: 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: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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: path.join(__dirname, './fixtures/index.js'),
9+
output: {
10+
path: path.join(__dirname, './dist'),
11+
filename: '[name].js'
12+
},
13+
plugins: [
14+
new HtmlWebpackPlugin({
15+
template: path.resolve(__dirname, './fixtures/index.html'),
16+
filename: path.join(__dirname, './dist/frontend/index.html')
17+
}),
18+
new Self()
19+
]
20+
};
21+
22+
export default config;

‎src/HtmlInlineScriptPlugin.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import path from 'path';
12
import { Compilation } from 'webpack';
23
import type { Compiler, WebpackPluginInstance } from 'webpack';
34
import htmlWebpackPlugin from 'html-webpack-plugin';
@@ -37,7 +38,7 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
3738
const {
3839
scriptMatchPattern = [/.+[.]js$/],
3940
htmlMatchPattern = [/.+[.]html$/],
40-
assetPreservePattern = [],
41+
assetPreservePattern = []
4142
} = options;
4243

4344
this.scriptMatchPattern = scriptMatchPattern;
@@ -59,7 +60,6 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
5960
return this.assetPreservePattern.some((test) => assetName.match(test));
6061
}
6162

62-
6363
shouldProcessHtml(
6464
templateName: string
6565
): boolean {
@@ -102,18 +102,48 @@ class HtmlInlineScriptPlugin implements WebpackPluginInstance {
102102
};
103103
}
104104

105-
apply(compiler: Compiler): void {
106-
let publicPath = compiler.options?.output?.publicPath as string || '';
105+
getPublicPath(
106+
compilation: Compilation,
107+
htmlFileName: string,
108+
customPublicPath: string
109+
): string {
110+
const webpackPublicPath = compilation.getAssetPath(
111+
compilation.outputOptions.publicPath as string,
112+
{ hash: compilation.hash }
113+
);
114+
// Webpack 5 introduced "auto" as default value
115+
const isPublicPathDefined = webpackPublicPath !== 'auto';
116+
117+
let publicPath = '';
118+
119+
if (customPublicPath !== 'auto') {
120+
// If the html-webpack-plugin options contain a custom public path uset it
121+
publicPath = customPublicPath;
122+
} else if (isPublicPathDefined) {
123+
// If a hard coded public path exists in webpack config use it
124+
publicPath = webpackPublicPath;
125+
} else if (compilation.options.output.path) {
126+
// If no public path for webpack and html-webpack-plugin was set get a relative url path
127+
publicPath = path.relative(
128+
path.resolve(compilation.options.output.path, path.dirname(htmlFileName)),
129+
compilation.options.output.path
130+
).split(path.sep).join('/');
131+
}
107132

108133
if (publicPath && !publicPath.endsWith('/')) {
109134
publicPath += '/';
110135
}
111136

137+
return publicPath;
138+
}
139+
140+
apply(compiler: Compiler): void {
112141
compiler.hooks.compilation.tap(`${PLUGIN_PREFIX}_compilation`, (compilation) => {
113142
const hooks = htmlWebpackPlugin.getHooks(compilation);
114143

115144
hooks.alterAssetTags.tap(`${PLUGIN_PREFIX}_alterAssetTags`, (data) => {
116145
const htmlFileName = data.plugin.options?.filename;
146+
const publicPath = this.getPublicPath(compilation, data.outputName, data.publicPath);
117147

118148
if (htmlFileName && !this.shouldProcessHtml(htmlFileName)) {
119149
this.ignoredHtmlFiles.push(htmlFileName);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /