Skip to content

docs(rfc): create file naming guidelines for convergence#16870

Closed
Hotell wants to merge 4 commits intomicrosoft:masterfrom
Hotell:hotell/rfc/convergence-file-naming
Closed

docs(rfc): create file naming guidelines for convergence#16870
Hotell wants to merge 4 commits intomicrosoft:masterfrom
Hotell:hotell/rfc/convergence-file-naming

Conversation

@Hotell
Copy link
Copy Markdown
Contributor

@Hotell Hotell commented Feb 8, 2021

Description of changes

Based on #16806, this RFC attempts to implement consistency for naming converged packages files with proper intent.

NOTE:

  • make sure to read in in preview mode, otherwise the Table is quiet unreadable
  • It's a Draft PR, will promote this to READY after initial round of feedback.

Focus areas to test

(optional)

Comment thread rfcs/convergence/file-naming.md Outdated
- some files are PascalCased, some camelCased
- not explicitly communicating the intent
- what does `use` mean ?
- seasoned react dev will probably guess that it's a hook. Thing is, that this file might export more that 1 hook.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's a great catch!

<!-- This is the bulk of the RFC. Explain the proposal or design in enough detail for the inteded audience to understand. -->

- use consistent names for all files.
- follow a pattern that describes the symbol's feature or the file scope(component name) then its type.
Copy link
Copy Markdown
Contributor

@kubkon kubkon Feb 8, 2021

Choose a reason for hiding this comment

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

Suggested change
- follow a pattern that describes the symbol's feature or the file scope(component name) then its type.
- Follow a pattern that describes the symbol's feature or the file scope (component name) followed by its type.

Comment thread rfcs/convergence/file-naming.md
Comment thread rfcs/convergence/file-naming.md Outdated
| Current File Name | Proposed File name | Symbol Name | Remarks |
| ------------------- | ------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| index.tsx | index.ts | | No changes from current |
| Example.tsx | example.ts | `export const Example = () => {..}` | To enforce rendering logic only within `.view.` type file/s. TS will enforce this by default. Not extremely picky on this one, we can use `.tsx` as well to match extension with test/story - priority is to be consistent |
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Personally, I find the naming Example.tsx to be intuitive since it tells me we're exporting an object/component/etc. In fact, this is how the naming convention works in Zig as well for instance - if a module is in fact a struct, then name it as capital such as Example; otherwise, lowercase.

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.

I hear you. Just note that this is primarily about having consistency.

@size-auditor
Copy link
Copy Markdown

size-auditor Bot commented Feb 8, 2021

Asset size changes

Size Auditor did not detect a change in bundle size for any component!

Baseline commit: 0dbe8a2d955f2a9a589aef6797654a94d53bcc4f (build)

Comment thread rfcs/convergence/file-naming.md Outdated
@codesandbox-ci
Copy link
Copy Markdown

codesandbox-ci Bot commented Feb 8, 2021

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.

Latest deployment of this branch, based on commit 8888008:

Sandbox Source
Fluent UI Button Configuration
codesandbox-react-template Configuration
codesandbox-react-northstar-template Configuration

@fabricteam
Copy link
Copy Markdown
Collaborator

fabricteam commented Feb 8, 2021

Perf Analysis

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 819 828 5000
BaseButton mount 968 974 5000
Breadcrumb mount 42702 42944 5000
ButtonNext mount 733 717 5000
Checkbox mount 1577 1592 5000
CheckboxBase mount 1308 1326 5000
ChoiceGroup mount 4941 4999 5000
ComboBox mount 960 966 1000
CommandBar mount 10093 10084 1000
ContextualMenu mount 6185 6121 1000
DefaultButton mount 1200 1193 5000
DetailsRow mount 3795 3782 5000
DetailsRowFast mount 3700 3709 5000
DetailsRowNoStyles mount 3535 3622 5000
Dialog mount 1503 1498 1000
DocumentCardTitle mount 1836 1827 1000
Dropdown mount 3419 3395 5000
FocusTrapZone mount 1778 1769 5000
FocusZone mount 1789 1752 5000
IconButton mount 1876 1880 5000
Label mount 333 339 5000
Layer mount 1848 1825 5000
Link mount 475 488 5000
MakeStyles mount 1947 1922 50000
MenuButton mount 1564 1523 5000
MessageBar mount 1986 2008 5000
Nav mount 3374 3390 1000
OverflowSet mount 1040 1040 5000
Panel mount 1467 1470 1000
Persona mount 881 906 1000
Pivot mount 1450 1457 1000
PrimaryButton mount 1314 1338 5000
Rating mount 7876 7845 5000
SearchBox mount 1390 1420 5000
Shimmer mount 2651 2716 5000
Slider mount 1925 1962 5000
SpinButton mount 5123 5201 5000
Spinner mount 413 410 5000
SplitButton mount 3278 3262 5000
Stack mount 525 527 5000
StackWithIntrinsicChildren mount 1510 1562 5000
StackWithTextChildren mount 4660 4758 5000
SwatchColorPicker mount 10350 10421 5000
Tabs mount 1411 1440 1000
TagPicker mount 2865 2882 5000
TeachingBubble mount 11671 11666 5000
Text mount 425 432 5000
TextField mount 1454 1402 5000
ThemeProvider mount 1396 1424 5000
ThemeProvider virtual-rerender 601 594 5000
ThemeProviderNext mount 2199 2176 5000
Toggle mount 812 837 5000
buttonNative mount 106 117 5000

Perf Analysis (Fluent)

Perf comparison
Status Scenario Fluent TPI Fabric TPI Ratio Iterations Ticks
🦄 Avatar.Fluent 0.18 0.56 0.32:1 2000 363
🦄 Button.Fluent 0.13 0.22 0.59:1 5000 640
🔧 Checkbox.Fluent 0.66 0.35 1.89:1 1000 662
🎯 Dialog.Fluent 0.17 0.22 0.77:1 5000 858
🔧 Dropdown.Fluent 3.1 0.42 7.38:1 1000 3104
🔧 Icon.Fluent 0.15 0.06 2.5:1 5000 727
🦄 Image.Fluent 0.09 0.13 0.69:1 5000 441
🔧 Slider.Fluent 1.59 0.47 3.38:1 1000 1589
🔧 Text.Fluent 0.08 0.03 2.67:1 5000 397
🦄 Tooltip.Fluent 0.12 0.9 0.13:1 5000 592

🔧 Needs work     🎯 On target     🦄 Amazing

Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
BoxMinimalPerf.default 442 406 1.09:1
SegmentMinimalPerf.default 429 395 1.09:1
TreeWith60ListItems.default 199 183 1.09:1
PortalMinimalPerf.default 181 168 1.08:1
DividerMinimalPerf.default 438 409 1.07:1
FormMinimalPerf.default 497 464 1.07:1
ListCommonPerf.default 748 706 1.06:1
LayoutMinimalPerf.default 483 461 1.05:1
AttachmentMinimalPerf.default 186 179 1.04:1
CarouselMinimalPerf.default 545 522 1.04:1
DropdownManyItemsPerf.default 792 765 1.04:1
ItemLayoutMinimalPerf.default 1383 1335 1.04:1
RefMinimalPerf.default 255 246 1.04:1
Tooltip.Fluent 592 569 1.04:1
AvatarMinimalPerf.default 226 220 1.03:1
ButtonMinimalPerf.default 208 202 1.03:1
ChatDuplicateMessagesPerf.default 397 386 1.03:1
FlexMinimalPerf.default 347 337 1.03:1
ListMinimalPerf.default 590 573 1.03:1
SplitButtonMinimalPerf.default 4080 3968 1.03:1
TooltipMinimalPerf.default 873 851 1.03:1
AttachmentSlotsPerf.default 1304 1277 1.02:1
ButtonUseCssNestingPerf.default 1157 1135 1.02:1
ChatWithPopoverPerf.default 461 450 1.02:1
ImageMinimalPerf.default 464 457 1.02:1
InputMinimalPerf.default 1365 1343 1.02:1
ListWith60ListItems.default 697 686 1.02:1
MenuMinimalPerf.default 1000 980 1.02:1
PopupMinimalPerf.default 741 723 1.02:1
RadioGroupMinimalPerf.default 511 499 1.02:1
ReactionMinimalPerf.default 466 456 1.02:1
TableManyItemsPerf.default 2289 2247 1.02:1
Dialog.Fluent 858 840 1.02:1
ButtonSlotsPerf.default 638 632 1.01:1
ButtonUseCssPerf.default 893 881 1.01:1
DatepickerMinimalPerf.default 49744 49138 1.01:1
EmbedMinimalPerf.default 4473 4442 1.01:1
HeaderMinimalPerf.default 425 422 1.01:1
HeaderSlotsPerf.default 888 881 1.01:1
LabelMinimalPerf.default 477 470 1.01:1
LoaderMinimalPerf.default 769 762 1.01:1
MenuButtonMinimalPerf.default 1711 1693 1.01:1
StatusMinimalPerf.default 813 803 1.01:1
IconMinimalPerf.default 733 723 1.01:1
TextAreaMinimalPerf.default 558 550 1.01:1
CustomToolbarPrototype.default 3783 3758 1.01:1
ToolbarMinimalPerf.default 1071 1063 1.01:1
Button.Fluent 640 633 1.01:1
Image.Fluent 441 438 1.01:1
ChatMinimalPerf.default 674 671 1:1
DialogMinimalPerf.default 855 856 1:1
ProviderMinimalPerf.default 962 960 1:1
SliderMinimalPerf.default 1581 1583 1:1
TableMinimalPerf.default 462 463 1:1
Checkbox.Fluent 662 665 1:1
Dropdown.Fluent 3104 3092 1:1
Icon.Fluent 727 728 1:1
Slider.Fluent 1589 1594 1:1
AlertMinimalPerf.default 337 340 0.99:1
AnimationMinimalPerf.default 440 443 0.99:1
CardMinimalPerf.default 637 641 0.99:1
CheckboxMinimalPerf.default 2923 2957 0.99:1
ListNestedPerf.default 652 660 0.99:1
RosterPerf.default 1281 1299 0.99:1
SkeletonMinimalPerf.default 416 419 0.99:1
VideoMinimalPerf.default 717 721 0.99:1
AccordionMinimalPerf.default 181 184 0.98:1
ButtonOverridesMissPerf.default 1732 1759 0.98:1
ProviderMergeThemesPerf.default 1575 1601 0.98:1
TreeMinimalPerf.default 834 854 0.98:1
Text.Fluent 397 406 0.98:1
GridMinimalPerf.default 399 411 0.97:1
TextMinimalPerf.default 406 417 0.97:1
Avatar.Fluent 363 375 0.97:1
DropdownMinimalPerf.default 3039 3175 0.96:1

@Hotell Hotell added the Type: RFC Request for Feedback label Feb 9, 2021
@Hotell Hotell added this to the February Project Cycle 2021 milestone Feb 9, 2021
Comment thread rfcs/convergence/file-naming.md Outdated
Comment thread rfcs/convergence/file-naming.md
Comment thread rfcs/convergence/file-naming.md Outdated
| Current File Name | Proposed File name | Symbol Name | Remarks |
| ------------------- | ------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| index.tsx | index.ts | | No changes from current |
| Example.tsx | example.ts | `export const Example = () => {..}` | To enforce rendering logic only within `.view.` type file/s. TS will enforce this by default. Not extremely picky on this one, we can use `.tsx` as well to match extension with test/story - priority is to be consistent |
Copy link
Copy Markdown
Member

@layershifter layershifter Feb 11, 2021

Choose a reason for hiding this comment

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

Suggested change
| Example.tsx | example.ts | `export const Example = () => {..}` | To enforce rendering logic only within `.view.` type file/s. TS will enforce this by default. Not extremely picky on this one, we can use `.tsx` as well to match extension with test/story - priority is to be consistent |
| Example.tsx | Example.ts | `export const Example = () => {..}` |

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.

I provided explicit reasoning in this document. This kind of feedback is not very helpful TBH.

  • we are not react team
  • default exports are an anti-pattern (nor is fluent using that ECMA feature)
  • we can start passing links indefinitely, to showcase who uses what :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree with Shift on this one, I'd prefer to keep the uppercase filename basically for the reasons he listed.

  • Clearly indicates that this file exports a component (even if it doesn't contain any rendering logic)
  • Matches the name of the main/only export (not relevant for this purpose whether that export is default or named)
  • Matches the convention used by both v8 and v0 today, and is extremely common throughout the community. Even though nobody has declared this as the "official" convention, at least from briefly looking through other React component repos, it's harder to find a repo that doesn't use uppercase names for component files than one that does.

| ------------------- | ------------------- | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| index.tsx | index.ts | | No changes from current |
| Example.tsx | example.ts | `export const Example = () => {..}` | To enforce rendering logic only within `.view.` type file/s. TS will enforce this by default. Not extremely picky on this one, we can use `.tsx` as well to match extension with test/story - priority is to be consistent |
| Example.test.tsx | example.spec.tsx | `describe->it` | Integration test on JSDOM level (jest) for whole component |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
| Example.test.tsx | example.spec.tsx | `describe->it` | Integration test on JSDOM level (jest) for whole component |
| Example.test.tsx | Example.spec.tsx | `describe->it` | Integration test on JSDOM level (jest) for whole component |

If we will go with Pascal Case, this should be also in Pascal Case: https://github.com/microsoft/fluentui/pull/16870/files#r574385390

Comment thread rfcs/convergence/file-naming.md Outdated
| Example.test.tsx | example.spec.tsx | `describe->it` | Integration test on JSDOM level (jest) for whole component |
| storybook (NONE) | example.stories.tsx | `export const Example = () => {..}` | Specific file type for Storybook consumption. Main "starting" point for inner loop - daily development. |
| mdx (NONE) | example.stories.mdx | --- | Markdown(MDX) for consumer facing documentation(mainly for storybook at the moment, but can be transformed to any other tool that can parse MDX). |
| renderExample.tsx | example.view.tsx | `export const render = () => {..}` | `.render` might work as well, to match symbol name. |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

A function should not be named as render, it should be renderComponentName as we should avoid collisions in consumer imports. For example:

import { render } from 'react-dom'
import { render } from '@fluentui/react-button'
import { render } from '@fluentui/react-menu'

It also breaks DX on our side as if search will be used how many matches for render you will get?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For me, it's confusing to name files as example.view.tsx when a single export is renderExample function. It's not a common thing in React community:

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.

renderComponentName

That's a typo, thx.

A function should not be named as render, it should be renderComponentName as we should avoid collisions in consumer imports. For example:

FWIW that's not true :) consumer can name imported symbols anyhow he wants.

It also breaks DX on our side as if search will be used how many matches for render you will get?

maybe out of topic but my understanding was that those renderers are meant to be used solely per package/component

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

"consumer can name imported symbols anyhow he wants." - from my experience with navigating relatively large code bases - the more specificity you have in names and the more consistency there is between file and export names, the better - because then you can easily combine fulltext search and file name search

In 99% of the cases probably yes, renderers will be used only in the package and component. But if the consumer wants to extend the component and add/replace hooks in it, he can still import and reuse the render function.

| storybook (NONE) | example.stories.tsx | `export const Example = () => {..}` | Specific file type for Storybook consumption. Main "starting" point for inner loop - daily development. |
| mdx (NONE) | example.stories.mdx | --- | Markdown(MDX) for consumer facing documentation(mainly for storybook at the moment, but can be transformed to any other tool that can parse MDX). |
| renderExample.tsx | example.view.tsx | `export const render = () => {..}` | `.render` might work as well, to match symbol name. |
| useExample.ts | example.hook.ts | `export const useExample = () => {}` | main logic encapsulated under hook -> name should be the same as encapsulated component (in our case `example`) |
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

I'd just add that there are no existing conventions ratified in any kind of official community style-guide, nor in fluent ui org :) that's the primary aim of this RFC -> focus/ratification on consistency.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

That's fair, I used these repos as a reference to show a common pattern. Fluent's repo follows it, too, currently.
Another fair note will be, that there is an explicit naming convention for hooks, they should start with use*() keyword.

https://github.com/facebook/react/blob/483358c38f8623358dd44a3e57476bc02e6357bc/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js#L17-L19

**Why?**

- kebab case is more human readable especially in longer words
- mitigates issues with git on various OS/case in/consistent files systems (eg. rename `helloWorld` to `helloworld`, commit, push, merge... now someone wants to change it back to `helloWorld`... )
Copy link
Copy Markdown
Member

@layershifter layershifter Feb 11, 2021

Choose a reason for hiding this comment

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

This is handled by TypeScript compiler via forceConsistentCasingInFileNames (https://www.typescriptlang.org/docs/handbook/compiler-options.html) and is enabled across the repo. Is it a real issue currently?


---

- use `.tsx` only for files that contain view/rendering related logic
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
- use `.tsx` only for files that contain view/rendering related logic
- use `.tsx` only for files that contain view/rendering related logic
- enable lint rule that will enforce one way

I suggest to add into proposal an ESLint rule for this, otherwise it's easy to fail this convention. There is jsx-filename-extension, but I have not seen a similar for TS files:

  • no JSX in files - use .ts
  • JSX in files - use .tsx (this is forced by compiler anyway)

@JustSlone
Copy link
Copy Markdown
Collaborator

Likely move to March

@Hotell
Copy link
Copy Markdown
Contributor Author

Hotell commented Mar 2, 2021

Status update:

  • Address feedback this week
  • Tue 9 Mar / Address feedback this week 🤞

March goal: merge or not :)

@JustSlone JustSlone removed this from the March Project Cycle 2021 milestone Mar 16, 2021
@msft-fluent-ui-bot
Copy link
Copy Markdown
Collaborator

Because this pull request has not had activity for over 150 days, we're automatically closing it for house-keeping purposes.

The pull request will still be available for reference. If it's still relevant to merge at some point, you can reopen or make a new version based on the latest code.

@msft-fluent-ui-bot msft-fluent-ui-bot added the Resolution: Soft Close Soft closing inactive issues over a certain period label Sep 28, 2021
@ecraig12345 ecraig12345 reopened this Sep 28, 2021
@ecraig12345 ecraig12345 removed the Resolution: Soft Close Soft closing inactive issues over a certain period label Sep 28, 2021
@fabricteam
Copy link
Copy Markdown
Collaborator

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
react-accordion
Accordion (including children components)
55.264 kB
17.411 kB
react-avatar
Avatar
56.703 kB
15.742 kB
react-badge
Badge
23.912 kB
7.039 kB
react-badge
CounterBadge
26.902 kB
7.753 kB
react-badge
PresenseBadge
237 B
177 B
react-button
Button
23.286 kB
7.057 kB
react-button
CompoundButton
28.598 kB
7.905 kB
react-button
MenuButton
25.48 kB
7.743 kB
react-button
Button
30.879 kB
8.858 kB
react-button
ToggleButton
32.986 kB
7.681 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
165.643 kB
46.977 kB
react-components
react-components: FluentProvider & webLightTheme
35.77 kB
11.405 kB
react-divider
Divider
15.428 kB
5.595 kB
react-image
Image
9.908 kB
3.994 kB
react-input
Input
31.652 kB
11.319 kB
react-label
Label
9.108 kB
3.729 kB
react-link
Link
11.669 kB
4.607 kB
react-make-styles
makeStaticStyles (runtime)
7.59 kB
3.321 kB
react-make-styles
makeStyles + mergeClasses (runtime)
22.136 kB
8.357 kB
react-make-styles
makeStyles + mergeClasses (build time)
2.558 kB
1.204 kB
react-menu
Menu (including children components)
103.459 kB
31.457 kB
react-menu
Menu (including selectable components)
105.735 kB
31.811 kB
react-popover
Popover
101.302 kB
30.397 kB
react-portal
Portal
6.725 kB
2.237 kB
react-positioning
usePopper
23.145 kB
7.942 kB
react-provider
FluentProvider
15.764 kB
5.784 kB
react-slider
RangedSlider
35.526 kB
10.639 kB
react-slider
Slider
32.506 kB
10.191 kB
react-switch
Switch
24.36 kB
7.858 kB
react-text
Text - Default
11.731 kB
4.443 kB
react-text
Text - Wrappers
15.353 kB
4.742 kB
react-theme
Teams: all themes
32.945 kB
6.677 kB
react-theme
Teams: Light theme
20.251 kB
5.665 kB
react-tooltip
Tooltip
45.74 kB
15.561 kB
react-utilities
SSRProvider
213 B
170 B
🤖 This report was generated against df5afae24db50bc4f82502a2c8de86115172caba

@msft-fluent-ui-bot
Copy link
Copy Markdown
Collaborator

Because this pull request has not had activity for over 150 days, we're automatically closing it for house-keeping purposes.

The pull request will still be available for reference. If it's still relevant to merge at some point, you can reopen or make a new version based on the latest code.

@msft-fluent-ui-bot msft-fluent-ui-bot added the Resolution: Soft Close Soft closing inactive issues over a certain period label Feb 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Resolution: Soft Close Soft closing inactive issues over a certain period Type: RFC Request for Feedback

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants