Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"specialattribute",
"dircompare",
"wagoid",
"autocrlf"
"autocrlf",
"Rspack"
],
"ignorePaths": [
"CHANGELOG.md",
Expand Down
6 changes: 6 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -640,11 +640,17 @@ class HtmlWebpackPlugin {
delete globalClone.eval;
delete globalClone.Function;
// Not using `...global` as it throws when localStorage is not explicitly enabled in Node 25+
// Provide a CommonJS-style `module`/`exports` pair so templates compiled as CommonJS
// (e.g. Rspack's child compilation output, which wraps the result in `module.exports = ...`)
// can assign to them instead of failing with `module is not defined`.
const sandboxModule = { exports: {} };
const vmContext = vm.createContext(
Object.assign(globalClone, {
HTML_WEBPACK_PLUGIN: true,
// Copying nonstandard globals like `require` explicitly as they may be absent from `global`
require: require,
module: sandboxModule,
exports: sandboxModule.exports,
htmlWebpackPluginPublicPath: publicPath,
__filename: templateWithoutLoaders,
__dirname: path.dirname(templateWithoutLoaders),
Expand Down
12 changes: 12 additions & 0 deletions spec/basic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3853,4 +3853,16 @@ describe("HtmlWebpackPlugin", () => {
done,
);
});

describe("evaluateCompilationResult", () => {
it("evaluates templates wrapped in a CommonJS `module.exports = ...` expression", () => {
const plugin = new HtmlWebpackPlugin();
const source = 'module.exports = "<!DOCTYPE html><title>ok</title>";';
return plugin
.evaluateCompilationResult(source, "", "template.js")
.then((result) => {
expect(result).toBe("<!DOCTYPE html><title>ok</title>");
});
});
});
});
Loading