Skip to content

feat(html): support async template function in module.parser.html.template#21098

Open
aryanraj45 wants to merge 2 commits into
webpack:mainfrom
aryanraj45:feat/html-template-async
Open

feat(html): support async template function in module.parser.html.template#21098
aryanraj45 wants to merge 2 commits into
webpack:mainfrom
aryanraj45:feat/html-template-async

Conversation

@aryanraj45
Copy link
Copy Markdown
Contributor

Summary

The module.parser.html.template option only supported synchronous functions. This adds Promise<string> return support, closing the html-loader preprocessor async parity gap.

Implemented by converting the per-module processResult hook from SyncWaterfallHook to AsyncSeriesWaterfallHook. Existing sync tappers (CSS, JS, TypeScript) are unaffected — .tap() callbacks remain valid on an async waterfall hook. A minor per-module async overhead applies to all module types; benchmarks should be checked.

What kind of change does this PR introduce?

feat

Did you add tests for your changes?

Yes — test/configCases/html/parser-template-async/. Covers async URL injection, addDependency, and emitWarning called after await.

Does this PR introduce a breaking change?

No. Sync templates continue to work unchanged.

If relevant, what needs to be documented once your changes are merged or what have you already documented?

module.parser.html.template docs should note it now accepts async functions / Promise<string>.

Use of AI
partial

…plate

Converts the per-module processResult hook (SyncWaterfallHook →
AsyncSeriesWaterfallHook) so the html template option can return a
Promise<string>. Existing sync tappers (CSS, JS, TS) are unaffected.
Copilot AI review requested due to automatic review settings June 4, 2026 11:12
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jun 4, 2026

⚠️ No Changeset found

Latest commit: 78bc142

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for asynchronous HTML template functions in the HTML parser pipeline by making the template application and the NormalModule processResult hook async-aware.

Changes:

  • Allow module.parser.html.template to return a Promise<string> in types and implementation.
  • Convert NormalModuleCompilationHooks.processResult from sync to async-waterfall and update call sites.
  • Add a new config-case test covering async template behavior and warning emission.

Reviewed changes

Copilot reviewed 7 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
types.d.ts Updates typings for async HTML template and async processResult hook.
lib/html/HtmlParser.js Implements Promise support for template / applyTemplate.
lib/html/HtmlModulesPlugin.js Awaits applyTemplate via processResult.tapPromise.
lib/NormalModule.js Migrates processResult hook to AsyncSeriesWaterfallHook and uses callAsync.
test/configCases/html/parser-template-async/* Adds a new test case and warning snapshot for async templates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread lib/html/HtmlParser.js Outdated
Comment on lines +836 to +851
if (typeof transformed === "string" || Buffer.isBuffer(transformed)) {
return transformed;
}
if (transformed instanceof Promise) {
return transformed.then((result) => {
if (typeof result !== "string") {
throw new Error(
"The `template` html parser option must return a string or Promise<string>."
);
}
return result;
});
}
return transformed;
throw new Error(
"The `template` html parser option must return a string or Promise<string>."
);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed 👍

Comment thread lib/html/HtmlParser.js
if (typeof transformed === "string" || Buffer.isBuffer(transformed)) {
return transformed;
}
if (transformed instanceof Promise) {
… path

Aligns sync and async template return type: both now accept only string /
Promise<string>. Buffer was silently accepted by the old sync path but was
never a valid use case for a text-transformation function.
Copy link
Copy Markdown
Member

@alexander-akait alexander-akait left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't touch this things right now, we need to make parser and generator async firstly, we already have a PR for generator, so async is postpone currently

@aryanraj45
Copy link
Copy Markdown
Contributor Author

Don't touch this things right now, we need to make parser and generator async firstly, we already have a PR for generator, so async is postpone currently

Got it lets wait for the parser/generator async foundation to be in place; will revisit and rebase after that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants