fix(web-components): use lib replacement for web types#32129
fix(web-components): use lib replacement for web types#32129radium-v wants to merge 9 commits intomicrosoft:masterfrom
Conversation
🕵 fluentui-web-components-v3 No visual regressions between this PR and main |
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| Avatar | mount | 658 | 635 | 5000 | |
| Button | mount | 309 | 319 | 5000 | |
| Field | mount | 1142 | 1151 | 5000 | |
| FluentProvider | mount | 725 | 693 | 5000 | |
| FluentProviderWithTheme | mount | 88 | 87 | 10 | |
| FluentProviderWithTheme | virtual-rerender | 32 | 34 | 10 | |
| FluentProviderWithTheme | virtual-rerender-with-unmount | 84 | 78 | 10 | |
| MakeStyles | mount | 871 | 861 | 50000 | |
| Persona | mount | 1779 | 1753 | 5000 | |
| SpinButton | mount | 1418 | 1384 | 5000 | |
| SwatchPicker | mount | 1701 | 1737 | 5000 |
🕵 fluentuiv8 No visual regressions between this PR and main |
📊 Bundle size report✅ No changes found |
🕵 FluentUIV0 No visual regressions between this PR and main |
Perf Analysis (
|
| Scenario | Current PR Ticks | Baseline Ticks | Ratio |
|---|---|---|---|
| AttachmentMinimalPerf.default | 91 | 78 | 1.17:1 |
| AvatarMinimalPerf.default | 114 | 103 | 1.11:1 |
| PortalMinimalPerf.default | 93 | 85 | 1.09:1 |
| RadioGroupMinimalPerf.default | 282 | 258 | 1.09:1 |
| FlexMinimalPerf.default | 166 | 154 | 1.08:1 |
| FormMinimalPerf.default | 235 | 219 | 1.07:1 |
| SegmentMinimalPerf.default | 203 | 189 | 1.07:1 |
| CardMinimalPerf.default | 321 | 304 | 1.06:1 |
| DividerMinimalPerf.default | 208 | 196 | 1.06:1 |
| PopupMinimalPerf.default | 367 | 347 | 1.06:1 |
| TableMinimalPerf.default | 239 | 225 | 1.06:1 |
| CarouselMinimalPerf.default | 269 | 255 | 1.05:1 |
| ChatMinimalPerf.default | 462 | 440 | 1.05:1 |
| ChatWithPopoverPerf.default | 209 | 199 | 1.05:1 |
| ListWith60ListItems.default | 364 | 348 | 1.05:1 |
| DialogMinimalPerf.default | 469 | 451 | 1.04:1 |
| ImageMinimalPerf.default | 234 | 226 | 1.04:1 |
| LabelMinimalPerf.default | 221 | 213 | 1.04:1 |
| AnimationMinimalPerf.default | 307 | 297 | 1.03:1 |
| AttachmentSlotsPerf.default | 638 | 617 | 1.03:1 |
| DropdownMinimalPerf.default | 1454 | 1408 | 1.03:1 |
| ProviderMergeThemesPerf.default | 670 | 651 | 1.03:1 |
| SliderMinimalPerf.default | 760 | 741 | 1.03:1 |
| SplitButtonMinimalPerf.default | 2281 | 2225 | 1.03:1 |
| StatusMinimalPerf.default | 400 | 387 | 1.03:1 |
| IconMinimalPerf.default | 385 | 373 | 1.03:1 |
| CustomToolbarPrototype.default | 1477 | 1435 | 1.03:1 |
| AlertMinimalPerf.default | 161 | 158 | 1.02:1 |
| ButtonSlotsPerf.default | 301 | 296 | 1.02:1 |
| CheckboxMinimalPerf.default | 1158 | 1140 | 1.02:1 |
| TextAreaMinimalPerf.default | 293 | 288 | 1.02:1 |
| DatepickerMinimalPerf.default | 3576 | 3556 | 1.01:1 |
| DropdownManyItemsPerf.default | 399 | 396 | 1.01:1 |
| HeaderSlotsPerf.default | 478 | 472 | 1.01:1 |
| LayoutMinimalPerf.default | 202 | 200 | 1.01:1 |
| RosterPerf.default | 1647 | 1623 | 1.01:1 |
| ButtonOverridesMissPerf.default | 656 | 653 | 1:1 |
| GridMinimalPerf.default | 189 | 189 | 1:1 |
| ItemLayoutMinimalPerf.default | 721 | 719 | 1:1 |
| ListNestedPerf.default | 330 | 329 | 1:1 |
| ProviderMinimalPerf.default | 205 | 204 | 1:1 |
| ToolbarMinimalPerf.default | 537 | 537 | 1:1 |
| VideoMinimalPerf.default | 435 | 434 | 1:1 |
| ChatDuplicateMessagesPerf.default | 149 | 150 | 0.99:1 |
| EmbedMinimalPerf.default | 1850 | 1868 | 0.99:1 |
| InputMinimalPerf.default | 546 | 549 | 0.99:1 |
| SkeletonMinimalPerf.default | 195 | 197 | 0.99:1 |
| TableManyItemsPerf.default | 1107 | 1116 | 0.99:1 |
| TextMinimalPerf.default | 194 | 196 | 0.99:1 |
| ListMinimalPerf.default | 308 | 313 | 0.98:1 |
| MenuMinimalPerf.default | 501 | 509 | 0.98:1 |
| ReactionMinimalPerf.default | 210 | 215 | 0.98:1 |
| TooltipMinimalPerf.default | 1298 | 1321 | 0.98:1 |
| BoxMinimalPerf.default | 191 | 197 | 0.97:1 |
| AccordionMinimalPerf.default | 85 | 89 | 0.96:1 |
| MenuButtonMinimalPerf.default | 951 | 988 | 0.96:1 |
| TreeMinimalPerf.default | 482 | 502 | 0.96:1 |
| ListCommonPerf.default | 381 | 405 | 0.94:1 |
| LoaderMinimalPerf.default | 188 | 201 | 0.94:1 |
| RefMinimalPerf.default | 102 | 108 | 0.94:1 |
| HeaderMinimalPerf.default | 193 | 208 | 0.93:1 |
| ButtonMinimalPerf.default | 84 | 91 | 0.92:1 |
| TreeWith60ListItems.default | 81 | 92 | 0.88:1 |
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| BaseButton | mount | 636 | 667 | 5000 | |
| Breadcrumb | mount | 1742 | 1689 | 1000 | |
| Checkbox | mount | 1695 | 1752 | 5000 | |
| CheckboxBase | mount | 1530 | 1477 | 5000 | |
| ChoiceGroup | mount | 3007 | 2968 | 5000 | |
| ComboBox | mount | 691 | 661 | 1000 | |
| CommandBar | mount | 6685 | 6641 | 1000 | |
| ContextualMenu | mount | 13166 | 13051 | 1000 | |
| DefaultButton | mount | 779 | 801 | 5000 | |
| DetailsRow | mount | 2233 | 2267 | 5000 | |
| DetailsRowFast | mount | 2233 | 2282 | 5000 | |
| DetailsRowNoStyles | mount | 2046 | 2052 | 5000 | |
| Dialog | mount | 2812 | 2791 | 1000 | |
| DocumentCardTitle | mount | 246 | 239 | 1000 | |
| Dropdown | mount | 2062 | 2028 | 5000 | |
| FocusTrapZone | mount | 1168 | 1168 | 5000 | |
| FocusZone | mount | 1133 | 1112 | 5000 | |
| GroupedList | mount | 38746 | 43398 | 2 | |
| GroupedList | virtual-rerender | 20936 | 21152 | 2 | |
| GroupedList | virtual-rerender-with-unmount | 53484 | 53013 | 2 | |
| GroupedListV2 | mount | 239 | 251 | 2 | |
| GroupedListV2 | virtual-rerender | 225 | 225 | 2 | |
| GroupedListV2 | virtual-rerender-with-unmount | 239 | 237 | 2 | |
| IconButton | mount | 1182 | 1169 | 5000 | |
| Label | mount | 341 | 358 | 5000 | |
| Layer | mount | 2837 | 2779 | 5000 | |
| Link | mount | 420 | 407 | 5000 | |
| MenuButton | mount | 975 | 998 | 5000 | |
| MessageBar | mount | 22242 | 22219 | 5000 | |
| Nav | mount | 2062 | 2080 | 1000 | |
| OverflowSet | mount | 832 | 807 | 5000 | |
| Panel | mount | 1876 | 1815 | 1000 | |
| Persona | mount | 754 | 760 | 1000 | |
| Pivot | mount | 947 | 913 | 1000 | |
| PrimaryButton | mount | 949 | 953 | 5000 | |
| Rating | mount | 4732 | 4881 | 5000 | |
| SearchBox | mount | 950 | 977 | 5000 | |
| Shimmer | mount | 1908 | 1955 | 5000 | |
| Slider | mount | 1358 | 1328 | 5000 | |
| SpinButton | mount | 3021 | 2995 | 5000 | |
| Spinner | mount | 409 | 408 | 5000 | |
| SplitButton | mount | 1943 | 1940 | 5000 | |
| Stack | mount | 438 | 432 | 5000 | |
| StackWithIntrinsicChildren | mount | 874 | 897 | 5000 | |
| StackWithTextChildren | mount | 2822 | 2825 | 5000 | |
| SwatchColorPicker | mount | 6536 | 6559 | 5000 | |
| TagPicker | mount | 1489 | 1486 | 5000 | |
| Text | mount | 398 | 408 | 5000 | |
| TextField | mount | 955 | 952 | 5000 | |
| ThemeProvider | mount | 884 | 886 | 5000 | |
| ThemeProvider | virtual-rerender | 604 | 593 | 5000 | |
| ThemeProvider | virtual-rerender-with-unmount | 1332 | 1340 | 5000 | |
| Toggle | mount | 644 | 649 | 5000 | |
| buttonNative | mount | 203 | 207 | 5000 |
Hotell
left a comment
There was a problem hiding this comment.
package are incorrectly including reference tags (/// ), which creates issues for projects which use @fluentui/web-components as a dev dependency.
this seems to me like issue in user land. folks should use skipLibCheck:true in their TS configs
the upgrade from TypeScript 4 to 5 exposed a tsconfig configuration error with the moduleResolution field.
what kind of error ? AFAIR moduleResolution node16 follows same resolution as
nodeNext
I already provided review on this approach some time ago #31807 (review)
this introduces another complex setup to our repo which should be avoided.
if you are ok with shipping leaking global types without proper type definitions to your users I'd suggest to write a simple script that removes those type references after build step from .d.ts files.
Note: it seems menu and menu-item expose these web types to public API surface
quickly checking the implementation code indeed those types do leak:

Summary:
- we should not land these monorepo setup changes
- there are multiple patterns how to go around these limitations
|
Created issue for leaking types #32194 |
645195e to
66ee4b8
Compare
|
Hi @Hotell, Using I reverted the We're not okay with shipping leaking types, which is what this PR is specifically intended to address. Writing a custom script to do what a few simple, standard, and recommended configuration adjustments already do, in a built-in way, doesn't make sense to me. |
| "@fluentui/web-components/@storybook/html" | ||
| "@fluentui/web-components/@storybook/html", | ||
| "@fluentui/web-components/@typescript/lib-dom" |
There was a problem hiding this comment.
The @typescript/lib-dom package is included in nohoist, since @types/web breaks in packages which target ES5. This ensures that this types override is scoped only to the web components package.
https://github.com/microsoft/TypeScript-DOM-Lib-Generator?tab=readme-ov-file#typeslib-minimum-target

There was a problem hiding this comment.
Thanks for this - makes sense!
66ee4b8 to
1d6e88d
Compare
|
I reduced the changes down to only those related to the lib replacement, and fixing the type error in a utility class. |
|
I started looking into the leaking types issue and couldn't quite replicate your red squiggles, but after talking with @radium-v it seems that this PR would help fix the issue with As mentioned in the initial issue...
Could explain more about the concerns you have for the lib-replacement strategy landing in the web-components package? I'd like to fully understand the problems and perceived complexity. |
chrisdholt
left a comment
There was a problem hiding this comment.
Just a couple questions to confirm
| "@fluentui/web-components/@storybook/html" | ||
| "@fluentui/web-components/@storybook/html", | ||
| "@fluentui/web-components/@typescript/lib-dom" |
There was a problem hiding this comment.
Thanks for this - makes sense!
yes I'm aware what problem are we trying to solve. my proposal how to mitigate this is postprocessing within build step -> simple script to remove those reference pragmas, instead going route against monorepo setup and practices set in place ( NOTE: it's ok to opt out short term, if there is no clear workaround - which is not this case ) 🐞 NOTE: as I mentioned my(your) proposal will not mitigate leaking invalid public API problem.
true, but I'd suggest you to start encourage them to do so. Not using To add, our repo uses skipLibCheck in all packages. only use-case where this might matter to you is when you are authoring and shipping a library which has TS type emit as public api output and you commit to follow semver with it ( not application ) - which is our case ( we disable skipLibCheck when we generate public api interfaces ->
I guess everyone might perceive it differently, I don't see any "push aways" in those official docs. It would be nice to mention the perf and general recommendations in these docs indeed. The leaking types issue:
hope this answers your questions @davatron5000 . happy to discuss further if needed. ty |
|
I can "fix" the That said, the web-components project will always be a bit ahead of the curve on web platform feature we use, so the Per our hours of investigation into the issue...
We did some experiments yesterday and made the exact same demo repro you posted today and verified the With lib-replacement, the leaking types issue only surfaces if a downstream consumer tries to overrride/extend a function that uses newer types. At that point they are using newer types and would need to upgrade their lib-dom types to web-types. For downstream consumers in that situation (TS <= 5.4) we would not recommend If the web-component package's use of lib-replacement for web types with |
|
types or dependency alias?: whatever those docs say or encourage, its not completely "up to date/accurate" (also note those docs are 3 years old). In typescript, if you're dealing with global overrides/extensions , you should use global leaking types: That menu event is only one case, there are other occurences in your source code. Related to this, the proper API contract that 💡 If your source code had no issues with leaking these global types, that are not supported in every version of typescript, those reference pragmas would not be emitted at all = your 🚨 If you use dependency alias (as you propose in this PR) you'll never know about this problem (only if consumers would start creating issues). solution/recap:
happy to talk further |
|
Closing this in favor of #32308 |

Previous Behavior
The type declaration files generated for the
@fluentui/web-componentspackage are incorrectly including reference tags (/// <reference types="web" />), which creates issues for projects which use@fluentui/web-componentsas a dev dependency.Many new browser features we're using (like the Popover API) are sometimes too new to rely on the DOM types provided with the version of TypeScript in the repository, but these types are expected to be included with TypeScript over time, so we don't want to include them as a
typesreference.New Behavior
This PR uses lib replacement to replace the built-in
@typescript/lib-dompackage with@types/web, which prevents/// <reference types="web" />tags from being included in declaration files. The replaced types package is only included in theweb-components/package.jsonand is added to thenohoistlist to prevent it from being referenced outside of theweb-componentspackage.Additional changes:
MatchMediaStyleSheetBehaviorutility class.