Skip to content

Commit 22a1e4a

Browse files
committed
fix: handlebars preprocessor when a partial is used in both a Handlebars template and a JS template, #174
1 parent aa5e607 commit 22a1e4a

30 files changed

Lines changed: 180 additions & 56 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## 4.20.3 (2025-06-27)
4+
5+
- fix: handlebars preprocessor when a partial is used in both a Handlebars template and a JS template, #174
6+
- fix: handlebars preprocessor for the `compile` mode when a partial name contains `/` char
7+
38
## 4.20.2 (2025-04-17)
49

510
- fix: invalid values for `route.rewriteIndex` option are treated as default value

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html-bundler-webpack-plugin",
3-
"version": "4.20.2",
3+
"version": "4.20.3",
44
"description": "Generates complete single-page or multi-page website from source assets. Built-in support for Markdown, Eta, EJS, Handlebars, Nunjucks, Pug. Alternative to html-webpack-plugin.",
55
"keywords": [
66
"html",
@@ -147,7 +147,7 @@
147147
},
148148
"dependencies": {
149149
"@types/html-minifier-terser": "^7.0.2",
150-
"ansis": "3.17.0",
150+
"ansis": "4.1.0",
151151
"enhanced-resolve": ">=5.7.0",
152152
"eta": "^3.5.0",
153153
"html-minifier-terser": "^7.2.0"

src/Loader/Messages/Exeptions.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ const makeSerializable = require('webpack/lib/util/makeSerializable');
55
/** @typedef {import("webpack/lib/serialization/ObjectMiddleware").ObjectSerializerContext} ObjectSerializerContext */
66

77
const ansis = require('ansis');
8-
const { red, yellow, cyan, green, ansi256, cyanBright, reset, whiteBright, bgYellow } = require('ansis');
8+
const { red, yellow, cyan, green, fg, cyanBright, reset, whiteBright, bgYellow } = require('ansis');
99
const Config = require('../../Common/Config');
1010

1111
const { pluginLabel } = Config.get();
1212

13-
const redBright = ansi256(203);
13+
const redBright = fg(203);
1414
const pluginHeaderHtml = `<span style="color:#e36049">[${pluginLabel}]</span>`;
1515

1616
class LoaderException extends WebpackError {

src/Loader/Preprocessors/Handlebars/index.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,11 @@ const preprocessor = (loaderContext, options) => {
113113

114114
const template = fs.readFileSync(partialFile, 'utf8');
115115
Handlebars.registerPartial(name, template);
116+
117+
if (!('_sourcePartials' in Handlebars)) {
118+
Handlebars._sourcePartials = {};
119+
}
120+
Handlebars._sourcePartials[name] = template;
116121
}
117122
};
118123

@@ -219,15 +224,26 @@ const preprocessor = (loaderContext, options) => {
219224
let compiled;
220225

221226
try {
227+
if (typeof source == 'function') {
228+
// Handlebars.precompile requires a string.
229+
// However, if a partial is used in both a Handlebars template and a JS template,
230+
// it may already be compiled into a function.
231+
// In that case, we retrieve the original source from the `_sourcePartials` property,
232+
// where it was previously saved in `updatePartials()`.
233+
source = Handlebars._sourcePartials[name];
234+
}
222235
compiled = Handlebars.precompile(source, options);
223236
} catch (error) {
224237
let message = `Could not compile partial '${name}', in the template: ${resourcePath}`;
225238
throw new Error(message + '\n' + error.toString());
226239
}
227240

241+
// normalize the name to variable-safe name
242+
const varName = name.replace(/[\/-]/g, '_');
243+
228244
precompiledPartials += `
229-
var partial_${name} = ${compiled};
230-
Handlebars.partials['${name}'] = Handlebars.template(partial_${name});
245+
var partial_${varName} = ${compiled};
246+
Handlebars.partials['${name}'] = Handlebars.template(partial_${varName});
231247
`;
232248
}
233249

test/cases/_preprocessor/js-tmpl-hbs-partials-in-hbs-js/expected/app.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>My Title</title>
5+
<script src="app.js" defer="defer"></script>
6+
</head>
7+
<body>
8+
<h1 class="header">HEADER</h1> <h3>Sub header: this partial used in HBS-template</h3> <div>Person: Heisenberg, 50</div>
9+
<div id="app"></div>
10+
</body>
11+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{{#> layout}}
2+
{{#*inline "navContainer"}}
3+
{{> nav}}
4+
{{/inline}}
5+
{{#*inline "contentContainer"}}
6+
{{> content}}
7+
{{/inline}}
8+
{{#*inline "footerContainer"}}
9+
{{> footer}}
10+
{{/inline}}
11+
{{/layout}}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import tmpl from './app.hbs';
2+
3+
const locals = {
4+
helloName: 'World',
5+
name: 'Max',
6+
age: 21,
7+
navText: 'Navigation',
8+
};
9+
10+
document.getElementById('app').innerHTML = tmpl(locals);
11+
12+
console.log('>> app');

0 commit comments

Comments
 (0)