diff --git a/.cspell.json b/.cspell.json index 1352c7ac5..a4b3b91e9 100644 --- a/.cspell.json +++ b/.cspell.json @@ -28,7 +28,8 @@ "specialattribute", "dircompare", "wagoid", - "autocrlf" + "autocrlf", + "Rspack" ], "ignorePaths": [ "CHANGELOG.md", diff --git a/index.js b/index.js index 28fc0ede4..34df47f5e 100644 --- a/index.js +++ b/index.js @@ -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), diff --git a/spec/basic.spec.js b/spec/basic.spec.js index 648c7944f..b9952df28 100644 --- a/spec/basic.spec.js +++ b/spec/basic.spec.js @@ -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 = "ok";'; + return plugin + .evaluateCompilationResult(source, "", "template.js") + .then((result) => { + expect(result).toBe("ok"); + }); + }); + }); });