chore: add React Compiler eslint rule#31457
Conversation
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
4aaec5b to
b360d2c
Compare
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| Avatar | mount | 611 | 618 | 5000 | |
| Button | mount | 306 | 302 | 5000 | |
| Field | mount | 1118 | 1077 | 5000 | |
| FluentProvider | mount | 712 | 691 | 5000 | |
| FluentProviderWithTheme | mount | 87 | 83 | 10 | |
| FluentProviderWithTheme | virtual-rerender | 34 | 33 | 10 | |
| FluentProviderWithTheme | virtual-rerender-with-unmount | 73 | 73 | 10 | |
| MakeStyles | mount | 869 | 866 | 50000 | |
| Persona | mount | 1772 | 1707 | 5000 | |
| SpinButton | mount | 1417 | 1425 | 5000 | |
| SwatchPicker | mount | 1633 | 1651 | 5000 |
Perf Analysis (
|
| Scenario | Current PR Ticks | Baseline Ticks | Ratio |
|---|---|---|---|
| ButtonMinimalPerf.default | 98 | 85 | 1.15:1 |
| TreeWith60ListItems.default | 92 | 81 | 1.14:1 |
| GridMinimalPerf.default | 199 | 176 | 1.13:1 |
| FlexMinimalPerf.default | 169 | 152 | 1.11:1 |
| PortalMinimalPerf.default | 92 | 83 | 1.11:1 |
| ProviderMinimalPerf.default | 208 | 192 | 1.08:1 |
| ChatDuplicateMessagesPerf.default | 158 | 147 | 1.07:1 |
| LabelMinimalPerf.default | 223 | 209 | 1.07:1 |
| BoxMinimalPerf.default | 199 | 188 | 1.06:1 |
| ButtonSlotsPerf.default | 319 | 300 | 1.06:1 |
| ListNestedPerf.default | 330 | 311 | 1.06:1 |
| VideoMinimalPerf.default | 456 | 430 | 1.06:1 |
| ReactionMinimalPerf.default | 216 | 206 | 1.05:1 |
| SegmentMinimalPerf.default | 202 | 192 | 1.05:1 |
| IconMinimalPerf.default | 398 | 380 | 1.05:1 |
| MenuMinimalPerf.default | 509 | 490 | 1.04:1 |
| SliderMinimalPerf.default | 747 | 719 | 1.04:1 |
| TableMinimalPerf.default | 239 | 230 | 1.04:1 |
| RosterPerf.default | 1614 | 1572 | 1.03:1 |
| RadioGroupMinimalPerf.default | 271 | 262 | 1.03:1 |
| TableManyItemsPerf.default | 1104 | 1075 | 1.03:1 |
| TooltipMinimalPerf.default | 1288 | 1249 | 1.03:1 |
| AnimationMinimalPerf.default | 304 | 299 | 1.02:1 |
| ButtonOverridesMissPerf.default | 672 | 656 | 1.02:1 |
| ChatWithPopoverPerf.default | 205 | 201 | 1.02:1 |
| CheckboxMinimalPerf.default | 1166 | 1148 | 1.02:1 |
| DialogMinimalPerf.default | 440 | 433 | 1.02:1 |
| DividerMinimalPerf.default | 205 | 200 | 1.02:1 |
| LayoutMinimalPerf.default | 204 | 200 | 1.02:1 |
| ListWith60ListItems.default | 371 | 363 | 1.02:1 |
| ProviderMergeThemesPerf.default | 656 | 644 | 1.02:1 |
| SkeletonMinimalPerf.default | 198 | 195 | 1.02:1 |
| SplitButtonMinimalPerf.default | 2283 | 2237 | 1.02:1 |
| TextMinimalPerf.default | 198 | 195 | 1.02:1 |
| TextAreaMinimalPerf.default | 293 | 287 | 1.02:1 |
| CardMinimalPerf.default | 302 | 299 | 1.01:1 |
| HeaderMinimalPerf.default | 208 | 205 | 1.01:1 |
| ItemLayoutMinimalPerf.default | 708 | 698 | 1.01:1 |
| ListMinimalPerf.default | 306 | 303 | 1.01:1 |
| PopupMinimalPerf.default | 350 | 348 | 1.01:1 |
| AttachmentSlotsPerf.default | 632 | 631 | 1:1 |
| DatepickerMinimalPerf.default | 3517 | 3515 | 1:1 |
| DropdownMinimalPerf.default | 1419 | 1414 | 1:1 |
| EmbedMinimalPerf.default | 1869 | 1862 | 1:1 |
| FormMinimalPerf.default | 233 | 233 | 1:1 |
| HeaderSlotsPerf.default | 461 | 461 | 1:1 |
| InputMinimalPerf.default | 547 | 545 | 1:1 |
| RefMinimalPerf.default | 111 | 111 | 1:1 |
| StatusMinimalPerf.default | 387 | 386 | 1:1 |
| CustomToolbarPrototype.default | 1451 | 1456 | 1:1 |
| AccordionMinimalPerf.default | 80 | 81 | 0.99:1 |
| DropdownManyItemsPerf.default | 400 | 404 | 0.99:1 |
| ImageMinimalPerf.default | 226 | 228 | 0.99:1 |
| MenuButtonMinimalPerf.default | 939 | 953 | 0.99:1 |
| TreeMinimalPerf.default | 471 | 477 | 0.99:1 |
| ChatMinimalPerf.default | 432 | 441 | 0.98:1 |
| ToolbarMinimalPerf.default | 532 | 544 | 0.98:1 |
| AvatarMinimalPerf.default | 106 | 109 | 0.97:1 |
| CarouselMinimalPerf.default | 262 | 273 | 0.96:1 |
| ListCommonPerf.default | 373 | 389 | 0.96:1 |
| AlertMinimalPerf.default | 154 | 162 | 0.95:1 |
| LoaderMinimalPerf.default | 183 | 193 | 0.95:1 |
| AttachmentMinimalPerf.default | 73 | 84 | 0.87:1 |
🕵 FluentUIV0 No visual regressions between this PR and main |
📊 Bundle size reportUnchanged fixtures
|
Perf Analysis (
|
| Scenario | Render type | Master Ticks | PR Ticks | Iterations | Status |
|---|---|---|---|---|---|
| BaseButton | mount | 641 | 621 | 5000 | |
| Breadcrumb | mount | 1686 | 1682 | 1000 | |
| Checkbox | mount | 1733 | 1720 | 5000 | |
| CheckboxBase | mount | 1474 | 1496 | 5000 | |
| ChoiceGroup | mount | 3002 | 2958 | 5000 | |
| ComboBox | mount | 695 | 677 | 1000 | |
| CommandBar | mount | 6536 | 6528 | 1000 | |
| ContextualMenu | mount | 12727 | 12962 | 1000 | |
| DefaultButton | mount | 779 | 800 | 5000 | |
| DetailsRow | mount | 2254 | 2213 | 5000 | |
| DetailsRowFast | mount | 2221 | 2255 | 5000 | |
| DetailsRowNoStyles | mount | 2069 | 2047 | 5000 | |
| Dialog | mount | 2812 | 2657 | 1000 | |
| DocumentCardTitle | mount | 227 | 228 | 1000 | |
| Dropdown | mount | 2031 | 2061 | 5000 | |
| FocusTrapZone | mount | 1151 | 1166 | 5000 | |
| FocusZone | mount | 1080 | 1086 | 5000 | |
| GroupedList | mount | 38462 | 43280 | 2 | |
| GroupedList | virtual-rerender | 18320 | 20396 | 2 | |
| GroupedList | virtual-rerender-with-unmount | 51498 | 51321 | 2 | |
| GroupedListV2 | mount | 223 | 228 | 2 | |
| GroupedListV2 | virtual-rerender | 215 | 217 | 2 | |
| GroupedListV2 | virtual-rerender-with-unmount | 232 | 227 | 2 | |
| IconButton | mount | 1114 | 1138 | 5000 | |
| Label | mount | 338 | 342 | 5000 | |
| Layer | mount | 2729 | 2746 | 5000 | |
| Link | mount | 388 | 383 | 5000 | |
| MenuButton | mount | 989 | 981 | 5000 | |
| MessageBar | mount | 21467 | 21492 | 5000 | |
| Nav | mount | 2024 | 2078 | 1000 | |
| OverflowSet | mount | 793 | 766 | 5000 | |
| Panel | mount | 1814 | 1845 | 1000 | |
| Persona | mount | 744 | 748 | 1000 | |
| Pivot | mount | 923 | 910 | 1000 | |
| PrimaryButton | mount | 936 | 962 | 5000 | |
| Rating | mount | 4689 | 4656 | 5000 | |
| SearchBox | mount | 925 | 915 | 5000 | |
| Shimmer | mount | 1939 | 1932 | 5000 | |
| Slider | mount | 1356 | 1339 | 5000 | |
| SpinButton | mount | 2992 | 2970 | 5000 | |
| Spinner | mount | 393 | 386 | 5000 | |
| SplitButton | mount | 1847 | 1871 | 5000 | |
| Stack | mount | 418 | 418 | 5000 | |
| StackWithIntrinsicChildren | mount | 856 | 864 | 5000 | |
| StackWithTextChildren | mount | 2697 | 2637 | 5000 | |
| SwatchColorPicker | mount | 6433 | 6485 | 5000 | |
| TagPicker | mount | 1456 | 1483 | 5000 | |
| Text | mount | 381 | 394 | 5000 | |
| TextField | mount | 950 | 956 | 5000 | |
| ThemeProvider | mount | 826 | 842 | 5000 | |
| ThemeProvider | virtual-rerender | 583 | 577 | 5000 | |
| ThemeProvider | virtual-rerender-with-unmount | 1299 | 1298 | 5000 | |
| Toggle | mount | 623 | 615 | 5000 | |
| buttonNative | mount | 201 | 195 | 5000 |
|
Note for everyone looking at files: These are the reasons why we need to turn off React forget in non-style files: Disabling exhaustive deps lint rule in hooks
Mutating params to a hook
Modifying state returned by a hook
Mutating a variable that React considers immutable
Conditionally calling hooks
Calling hooks from something that is not a functional component
Hook might be a different function on different renders
|
e4836b3 to
7118b55
Compare
15723db to
2b42d4a
Compare
Made an issue to follow up here: #31537 |
to clarify, this pragma is a proprietary thing that react-compiler eslint plugin understands + react-compiler will not be used in these places, correct ? |
Correct. |
|
@Hotell I took a lookt at
And it seems like you may have found a bug. The same repro but with I think we should keep the pragma across the board and report this as a bug against React Compiler. WDYT? |
78c62ea to
824d670
Compare
c90e418 to
2f29a4d
Compare
🕵 fluentuiv8 No visual regressions between this PR and main |
yes please, in general the rule should be - do not have/add things in our codebase that don't work :D |





Previous Behavior
No linting for the Rules of React.
New Behavior
Apologies for the massive PR but this change touches all or nearly all Fluent v9 components!
Adds
eslint-plugin-react-compiler. For background information on React Compiler (previously "React Forget") see: https://react.dev/learn/react-compilerWhile React Compiler require React 19, the eslint plugin does not.
This lint rule will help us adhere to the Rules of React much like the lint rule that enforces the Rules of Hooks.
The
"use no memo"directive is used to disable the linter rather than aneslint-disable-*comment as the directive will also instruct the actual React Forget compiler.Summary of changes