feat(html,css): support DefinePlugin text substitution in HTML and CS… - #21474
feat(html,css): support DefinePlugin text substitution in HTML and CS…#21474aryanraj45 wants to merge 3 commits into
Conversation
|
dfb057e to
15b32de
Compare
15b32de to
7f5073f
Compare
|
@alexander-akait can you please have a look at this thanks :)) |
7f5073f to
4abd787
Compare
…runs Replacements were recorded from a parse hook, so the parser still saw the original text: a URL built from a define resolved verbatim, and its own dependency ranges overlapped the ConstDependency ones. Rewriting the source from processResult fixes both and drops the parser hooks added for it. Also carries the module into runtimeValue (neither text parser has a `state`), records the main definitions hash so adding or removing a define invalidates a cached module, and keeps html/css defines out of the merged tree JavaScript object expansion reads.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7d01c44. Configure here.
| out += text.slice(last, from) + replacementCode; | ||
| last = to; | ||
| } | ||
| return [out + text.slice(last), ...rest]; |
There was a problem hiding this comment.
Rewritten source keeps stale loader source map
Medium Severity
The substituted text is returned together with the untouched loader source map from result, so mappings no longer line up with the emitted content. CSS/HTML modules produced by preprocessor loaders (for example sass-loader) with devtool enabled get silently misaligned source maps, and values containing newlines shift whole lines. TypeScriptPlugin composes an updated map when it rewrites source in the same hook.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7d01c44. Configure here.


Summary
DefinePluginonly tapped JS parsers, so HTML and CSS modules had no build-time identifier substitution. This adds an optional{ type: "html" | "css" }second argument toDefinePlugin, enabling%ENV_VAR%-style replacements in HTML and CSS source — matching what Vite does natively with%VITE_APP_TITLE%."javascript"(default) — existing behaviour, unchanged"html"— replaces any defined identifier in HTML module source before parsing"css"— replaces any defined identifier in CSS module source before parsing (all four CSS module types covered)Adds a
hooks.programSyncBailHooktoHtmlParserandCssParser, following the same pattern already established onJavascriptParser.What kind of change does this PR introduce?
feat
Did you add tests for your changes?
Yes —
test/configCases/html/define-plugin/(HTML substitution) andtest/configCases/css/define-plugin/(CSS substitution).Does this PR introduce a breaking change?
No. Omitting the second argument keeps the existing JS-only behaviour exactly as before.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
DefinePlugindocs should note the new optional{ type }option with an HTML/CSS example.Use of AI
Yes
Note
Medium Risk
Touches core
DefinePlugincompilation wiring and pre-parse source rewriting for HTML/CSS; incorrect substitution or cache keys could affect builds, but default JS behavior is preserved and behavior is covered by new config cases.Overview
DefinePluginnow accepts an optional second argument{ type?: "javascript" | "html" | "css" }(defaultjavascript). Existing JS behavior is unchanged when the option is omitted.For
type: "html"or"css", definitions are applied by substituting literal keys in the module source onNormalModule'sprocessResulthook (before HTML/CSS parsers run), so patterns like%BASE_URL%favicon.icoresolve correctly andDefinePlugin.runtimeValuestill works via a minimal parser shim. Replacements sort by longest key first to handle overlapping keys (e.g.process.envvsprocess.env.NODE_ENV), andvalueDependencies(including a main hash) tie into the same cache invalidation model as JS defines.html/cssinstances no longer merge into the shared JSdefinitionshook, so HTML-only keys cannot leak into JavaScript object expansion when a separate JSDefinePluginshares a prefix (e.g.CFG).Type definitions and config-case tests cover basic HTML/CSS substitution, URL/base-path cases, overlap, JS isolation, and CSS property replacement.
Reviewed by Cursor Bugbot for commit 7d01c44. Bugbot is set up for automated code reviews on this repo. Configure here.