Skip to content

Commit a059fcf

Browse files
committed
feat: add full support for public paths inside templates
1 parent e12a1ce commit a059fcf

File tree

5 files changed

+63
-6
lines changed

5 files changed

+63
-6
lines changed

index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class HtmlWebpackPlugin {
117117
* @param {string} templateFilename
118118
* @returns {Promise<string | (() => string | Promise<string>)>}
119119
*/
120-
evaluateCompilationResult (source, templateFilename) {
120+
evaluateCompilationResult (source, publicPath, templateFilename) {
121121
if (!source) {
122122
return Promise.reject(new Error('The child compilation didn\'t provide a result'));
123123
}
@@ -127,7 +127,7 @@ class HtmlWebpackPlugin {
127127
source += ';\nHTML_WEBPACK_PLUGIN_RESULT';
128128
}
129129
const templateWithoutLoaders = templateFilename.replace(/^.+!/, '').replace(/\?.+$/, '');
130-
const vmContext = vm.createContext({ HTML_WEBPACK_PLUGIN: true, require: require, ...global });
130+
const vmContext = vm.createContext({ HTML_WEBPACK_PLUGIN: true, require: require, htmlWebpackPluginPublicPath: publicPath, ...global });
131131
const vmScript = new vm.Script(source, { filename: templateWithoutLoaders });
132132
// Evaluate code and cast to string
133133
let newSource;
@@ -327,7 +327,7 @@ function hookIntoCompiler (compiler, options, plugin) {
327327
// Once everything is compiled evaluate the html factory
328328
// and replace it with its content
329329
return ('compiledEntry' in templateResult)
330-
? plugin.evaluateCompilationResult(templateResult.compiledEntry.content, options.template)
330+
? plugin.evaluateCompilationResult(templateResult.compiledEntry.content, htmlPublicPath, options.template)
331331
: Promise.reject(new Error('Child compilation contained no compiledEntry'));
332332
});
333333
const templateExectutionPromise = Promise.all([assetsPromise, assetTagGroupsPromise, templateEvaluationPromise])

lib/child-compiler.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,7 @@ class HtmlWebpackChildCompiler {
8888

8989
const outputOptions = {
9090
filename: '__child-[name]',
91-
publicPath: mainCompilation.outputOptions.publicPath === 'auto'
92-
? ''
93-
: mainCompilation.outputOptions.publicPath,
91+
publicPath: '',
9492
library: {
9593
type: 'var',
9694
name: 'HTML_WEBPACK_PLUGIN_RESULT'
@@ -116,6 +114,7 @@ class HtmlWebpackChildCompiler {
116114

117115
// Add all templates
118116
this.templates.forEach((template, index) => {
117+
new EntryPlugin(childCompiler.context, 'data:text/javascript,__webpack_public_path__ = htmlWebpackPluginPublicPath;', `HtmlWebpackPlugin_${index}-${this.id}`).apply(childCompiler);
119118
new EntryPlugin(childCompiler.context, template, `HtmlWebpackPlugin_${index}-${this.id}`).apply(childCompiler);
120119
});
121120

spec/basic.spec.js

+47
Original file line numberDiff line numberDiff line change
@@ -2584,4 +2584,51 @@ describe('HtmlWebpackPlugin', () => {
25842584
]
25852585
}, ['<script defer="defer" src="index_bundle.js"></script>'], null, done);
25862586
});
2587+
2588+
it('generates relative path for asset/resource', done => {
2589+
testHtmlPlugin({
2590+
mode: 'development',
2591+
entry: path.join(__dirname, 'fixtures/index.js'),
2592+
output: {
2593+
path: OUTPUT_DIR,
2594+
filename: 'index_bundle.js',
2595+
assetModuleFilename: 'assets/demo[ext]'
2596+
},
2597+
module: {
2598+
rules: [
2599+
{ test: /\.png$/, type: 'asset/resource' }
2600+
]
2601+
},
2602+
plugins: [
2603+
new HtmlWebpackPlugin({
2604+
template: 'html-loader!' + path.join(__dirname, 'fixtures/logo.html'),
2605+
filename: 'demo/index.js'
2606+
})
2607+
]
2608+
}, ['<img src="../assets/demo.png'], 'demo/index.js', done);
2609+
});
2610+
2611+
it('uses the absolute path for asset/resource', done => {
2612+
testHtmlPlugin({
2613+
mode: 'development',
2614+
entry: path.join(__dirname, 'fixtures/index.js'),
2615+
output: {
2616+
path: OUTPUT_DIR,
2617+
filename: 'index_bundle.js',
2618+
assetModuleFilename: 'assets/demo[ext]'
2619+
},
2620+
module: {
2621+
rules: [
2622+
{ test: /\.png$/, type: 'asset/resource' }
2623+
]
2624+
},
2625+
plugins: [
2626+
new HtmlWebpackPlugin({
2627+
template: 'html-loader!' + path.join(__dirname, 'fixtures/logo.html'),
2628+
filename: 'demo/index.js',
2629+
publicPath: '/foo/'
2630+
})
2631+
]
2632+
}, ['<img src="/foo/assets/demo.png'], 'demo/index.js', done);
2633+
});
25872634
});

spec/fixtures/logo.html

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en" manifest="foo.appcache">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Example Plain file</title>
6+
<meta name="viewport" content="width=device-width, initial-scale=1">
7+
</head>
8+
<body>
9+
<img src="./logo.png" />
10+
</body>
11+
</html>

spec/fixtures/logo.png

52.8 KB
Loading

0 commit comments

Comments
 (0)