fix(web-components): minify tagged templates in the ESM build#36387
fix(web-components): minify tagged templates in the ESM build#36387AKnassa wants to merge 1 commit into
Conversation
The ESM build (plain tsc output) shipped html/css tagged templates with literal newlines and indentation. Those whitespace-only text nodes render when a consumer sets a non-normal CSS white-space on an ancestor, breaking layout (observed on Label, Listbox, TextInput). The rollup bundles never had this problem because rollup.config.js runs rollup-plugin-fast-tagged-templates. Run that exact same transform over the tsc output in the compile step, so both builds ship byte-identical template content. Sourcemaps are remapped so dist/esm still traces back to the TypeScript sources. verify-packaging now asserts the shipped ESM is a fixed point of the transform, keeping the regression out for good. Fixes microsoft#36298
|
Hi @AKnassa, thanks for contributing. There's more to this issue than simply minifying the templates - it's a multi-part concern surrounding a few bugs. The original context for the linked issue is #36282, with #36298 and #36299 spawning off of it. Because of these similar-looking situations, I'd rather we go through the templates and try to adjust the existing whitespace in ways that can be safely mechanically minified. One possibility is changing indentation and newlines to be within tags (between attribute boundaries) so that we can retain readability in the source, while allowing for downstream consumers to decide how they want to process their bundles. This would alleviate any formatting ambiguity in the template structure, and help us identify places where whitespace in the shadow DOM is potentially meaningful so we can account for it in the CSS. |
Previous Behavior
The ESM build (
dist/esm, plaintscoutput) shipshtml/csstagged templates with the literal newlines and indentation used in the source for readability. Those whitespace-only text nodes land in every component's shadow DOM, and when an app sets a CSSwhite-spacevalue other thannormalon an ancestor, they suddenly render — components like Label, Listbox and TextInput grow stray gaps and look broken.The rollup bundles (
dist/web-components*.js) never had this problem, becauserollup.config.jsrunsrollup-plugin-fast-tagged-templates, which minifies the templates. So the two builds of the same package behaved differently.New Behavior
The compile step now runs that exact same plugin transform over the tsc output (new
scripts/minify-tagged-templates.js, called fromscripts/compile.js). Both builds now ship byte-identical template content — verified quasi-by-quasi across the affected components. Sourcemaps are re-mapped (@jridgewell/remapping) sodist/esmstill traces back to the TypeScript sources.To keep the bug from coming back,
scripts/verify-packaging.js(already wired into CI withdependsOn: build) now asserts that re-running the transform over every shippeddist/esm/**/*.jsfile is a no-op. Before this fix that check failed with 85 files; now the whole tree is a fixed point.Verified locally:
requiredLabel underwhite-space: prehas zero whitespace-only text nodes and identical dimensions towhite-space: normal, while the pre-fix template shows 3 stray text nodes and +19px height.label/text-input/listboxPlaywright specs pass in both CSR and SSR modes (170 tests), plus lint, type-check, and a clean uncached build.Notes for reviewers:
<svg>s in Option's checked indicator) are deliberately preserved by html-minifier-terser — identical to what the bundles ship today.*.template.tsfiles are untouched; authoring stays readable. The dev harness (vite/storybook, served fromsrc) is also unaffected.*.template.htmlfiles still contain prettier-formatted whitespace, so declarative-shadow-DOM output is still whitespace-sensitive. Happy to file a follow-up issue for that render path if wanted.rollup-plugin-fast-tagged-templatesas-is for parity — and since the issue is assigned to you, apologies if this crosses work you already had in flight; glad to adjust or hand off.Related Issue(s)