* Once webpack is done with compiling the template into a NodeJS code this function * evaluates it to generate the html result * * The evaluateCompilationResult is only a class function to allow spying during testing. * Please change that in a further refactoring * * @param {string
(source, publicPath, templateFilename)
| 616 | * @returns {Promise<string | (() => string | Promise<string>)>} |
| 617 | */ |
| 618 | evaluateCompilationResult(source, publicPath, templateFilename) { |
| 619 | if (!source) { |
| 620 | return Promise.reject( |
| 621 | new Error("The child compilation didn't provide a result"), |
| 622 | ); |
| 623 | } |
| 624 | |
| 625 | // The LibraryTemplatePlugin stores the template result in a local variable. |
| 626 | // By adding it to the end the value gets extracted during evaluation |
| 627 | if (source.indexOf("HTML_WEBPACK_PLUGIN_RESULT") >= 0) { |
| 628 | source += ";\nHTML_WEBPACK_PLUGIN_RESULT"; |
| 629 | } |
| 630 | |
| 631 | const templateWithoutLoaders = templateFilename |
| 632 | .replace(/^.+!/, "") |
| 633 | .replace(/\?.+$/, ""); |
| 634 | const globalClone = Object.create( |
| 635 | Object.getPrototypeOf(global), |
| 636 | Object.getOwnPropertyDescriptors(global), |
| 637 | ); |
| 638 | // Presence of `eval` and `Function` breaks template's explicit `eval` call |
| 639 | // Ref: https://github.com/nodejs/help/issues/2880 |
| 640 | delete globalClone.eval; |
| 641 | delete globalClone.Function; |
| 642 | // Not using `...global` as it throws when localStorage is not explicitly enabled in Node 25+ |
| 643 | // Provide a CommonJS-style `module`/`exports` pair so templates compiled as CommonJS |
| 644 | // (e.g. Rspack's child compilation output, which wraps the result in `module.exports = ...`) |
| 645 | // can assign to them instead of failing with `module is not defined`. |
| 646 | const sandboxModule = { exports: {} }; |
| 647 | const vmContext = vm.createContext( |
| 648 | Object.assign(globalClone, { |
| 649 | HTML_WEBPACK_PLUGIN: true, |
| 650 | // Copying nonstandard globals like `require` explicitly as they may be absent from `global` |
| 651 | require: require, |
| 652 | module: sandboxModule, |
| 653 | exports: sandboxModule.exports, |
| 654 | htmlWebpackPluginPublicPath: publicPath, |
| 655 | __filename: templateWithoutLoaders, |
| 656 | __dirname: path.dirname(templateWithoutLoaders), |
| 657 | }), |
| 658 | ); |
| 659 | |
| 660 | const vmScript = new vm.Script(source, { |
| 661 | filename: templateWithoutLoaders, |
| 662 | }); |
| 663 | |
| 664 | // Evaluate code and cast to string |
| 665 | let newSource; |
| 666 | |
| 667 | try { |
| 668 | newSource = vmScript.runInContext(vmContext); |
| 669 | } catch (e) { |
| 670 | return Promise.reject(e); |
| 671 | } |
| 672 | |
| 673 | if ( |
| 674 | typeof newSource === "object" && |
| 675 | newSource.__esModule && |
no outgoing calls
no test coverage detected