Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eslint-plugin): add autofixable import rules #22050

Closed

Conversation

Hotell
Copy link
Contributor

@Hotell Hotell commented Mar 10, 2022

Current Behavior

  1. lint rules from various plugins are not collocated - hard to read
  2. no module import consistency across whole monorepo

New Behavior

  1. lint rules from various plugins are collocated
  2. autofixable lint rules for consistent module imports

Fixable lint problems:

  • will be resolved automatically during pre-commit hook
  • can be triggered manually by user
after.mov
  • every problem will be autofixed, one at time, when hitting onSave in VSCode
after-autofix.mov

Remarks

Note that this will trigger probably a lot of lint warnings on CI. we should create task so people can follow up and apply autofixes by themselves gradually.

Follow up/replacement of this PR

#22128

Related Issue(s)

Fixes #22049
Fixes #18594

@codesandbox-ci
Copy link

codesandbox-ci bot commented Mar 10, 2022

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 33e3181:

Sandbox Source
@fluentui/react 8 starter Configuration
@fluentui/react-components 9 starter Configuration

@fabricteam
Copy link
Collaborator

fabricteam commented Mar 10, 2022

📊 Bundle size report

Unchanged fixtures
Package & Exports Size (minified/GZIP)
priority-overflow
createOverflowManager
2.836 kB
1.209 kB
react-accordion
Accordion (including children components)
74.658 kB
22.47 kB
react-avatar
Avatar
44.982 kB
13.059 kB
react-badge
Badge
20.869 kB
6.549 kB
react-badge
CounterBadge
21.737 kB
6.843 kB
react-badge
PresenceBadge
21.866 kB
6.536 kB
react-button
Button
28.013 kB
8.059 kB
react-button
CompoundButton
33.336 kB
9.037 kB
react-button
MenuButton
29.763 kB
8.656 kB
react-button
SplitButton
36.235 kB
9.857 kB
react-button
ToggleButton
37.395 kB
8.68 kB
react-card
Card - All
53.205 kB
15.27 kB
react-card
Card
48.898 kB
14.083 kB
react-card
CardFooter
7.653 kB
3.246 kB
react-card
CardHeader
8.931 kB
3.689 kB
react-card
CardPreview
7.626 kB
3.272 kB
react-combobox
Combobox
6.813 kB
2.895 kB
react-components
react-components: Accordion, Button, FluentProvider, Image, Menu, Popover
175.69 kB
48.974 kB
react-components
react-components: FluentProvider & webLightTheme
32.526 kB
10.645 kB
react-divider
Divider
15.301 kB
5.532 kB
react-image
Image
10.105 kB
3.952 kB
react-input
Input
21.538 kB
7.134 kB
react-label
Label
8.341 kB
3.487 kB
react-link
Link
11.102 kB
4.504 kB
react-menu
Menu (including children components)
105.599 kB
32.356 kB
react-menu
Menu (including selectable components)
107.954 kB
32.722 kB
react-popover
Popover
96.776 kB
29.553 kB
react-portal
Portal
6.267 kB
2.168 kB
react-positioning
usePopper
23.21 kB
8.084 kB
react-priority-overflow
hooks only
10.606 kB
4.087 kB
react-provider
FluentProvider
14.009 kB
5.25 kB
react-select
Select
7.754 kB
3.258 kB
react-slider
Slider
25.402 kB
8.251 kB
react-spinner
Spinner
6.811 kB
2.895 kB
react-switch
Switch
24.245 kB
7.986 kB
react-text
Text - Default
10.793 kB
4.23 kB
react-text
Text - Wrappers
14.107 kB
4.573 kB
react-theme
Single theme token import
69 B
89 B
react-theme
Teams: all themes
29.426 kB
6.551 kB
react-theme
Teams: Light theme
18.42 kB
5.27 kB
react-tooltip
Tooltip
42.76 kB
14.701 kB
react-utilities
SSRProvider
189 B
161 B
🤖 This report was generated against fcbdedc99e36f562680ebd2b1a7d422dabd5078b

@Hotell Hotell changed the title Hotell/improve eslint import rules eat(eslint-plugin): enable autofixable import rules Mar 10, 2022
@Hotell Hotell changed the title eat(eslint-plugin): enable autofixable import rules feat(eslint-plugin): enable autofixable import rules Mar 10, 2022
@fabricteam
Copy link
Collaborator

fabricteam commented Mar 10, 2022

Perf Analysis (@fluentui/react-components)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
Avatar mount 1074 1046 5000
Button mount 648 647 5000
FluentProvider mount 2099 2073 5000
FluentProviderWithTheme mount 325 288 10
FluentProviderWithTheme virtual-rerender 268 249 10
FluentProviderWithTheme virtual-rerender-with-unmount 310 345 10
MakeStyles mount 1798 1803 50000

@size-auditor
Copy link

size-auditor bot commented Mar 10, 2022

Asset size changes

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

Baseline commit: fcbdedc99e36f562680ebd2b1a7d422dabd5078b (build)

{
ignorePatterns: [
'require(<.*?>)?\\(',
'https?:\\/\\/',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

most of these changes is just re-ordering/collocation of rules

@@ -108,21 +88,15 @@ const config = {
'no-empty': 'error',
'no-eval': 'error',
'no-new-wrappers': 'error',
// handles only member sort, rest is handled via import/order
'sort-imports': ['warn', { ignoreDeclarationSort: true }],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

new rule - handles sorting members within import statements

@@ -273,15 +313,24 @@ const config = {
* @see https://github.com/import-js/eslint-plugin-import
*/
'import/no-extraneous-dependencies': ['error', { devDependencies: false }],
'import/no-duplicates': 'warn',
Copy link
Contributor Author

Choose a reason for hiding this comment

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

new rules

  • handles sorting imports by path
  • handles duplicate path imports
  • enforces to have imports always at the top of the file ( default behaviour of ECMAscript anyways - imports are hoisted )

@fabricteam
Copy link
Collaborator

fabricteam commented Mar 10, 2022

Perf Analysis (@fluentui/react-northstar)

⚠️ 1 potential perf regressions detected

Potential regressions comparing to master

Scenario Current PR Ticks Baseline Ticks Ratio Regression Analysis
PortalMinimalPerf.default 191 180 1.06:1 analysis
Perf tests with no regressions
Scenario Current PR Ticks Baseline Ticks Ratio
AccordionMinimalPerf.default 183 164 1.12:1
ButtonMinimalPerf.default 213 193 1.1:1
ListNestedPerf.default 662 602 1.1:1
DividerMinimalPerf.default 421 390 1.08:1
LayoutMinimalPerf.default 422 391 1.08:1
BoxMinimalPerf.default 393 367 1.07:1
FlexMinimalPerf.default 333 311 1.07:1
AttachmentMinimalPerf.default 189 178 1.06:1
TreeMinimalPerf.default 935 884 1.06:1
LabelMinimalPerf.default 447 427 1.05:1
TableMinimalPerf.default 478 455 1.05:1
TreeWith60ListItems.default 208 199 1.05:1
CardMinimalPerf.default 664 637 1.04:1
LoaderMinimalPerf.default 766 734 1.04:1
ReactionMinimalPerf.default 442 424 1.04:1
DatepickerMinimalPerf.default 6134 5962 1.03:1
ItemLayoutMinimalPerf.default 1351 1309 1.03:1
ListCommonPerf.default 716 693 1.03:1
VideoMinimalPerf.default 746 725 1.03:1
AnimationMinimalPerf.default 602 591 1.02:1
ChatWithPopoverPerf.default 448 438 1.02:1
FormMinimalPerf.default 481 471 1.02:1
HeaderMinimalPerf.default 415 407 1.02:1
ListWith60ListItems.default 707 696 1.02:1
ProviderMergeThemesPerf.default 1846 1803 1.02:1
RadioGroupMinimalPerf.default 521 513 1.02:1
AttachmentSlotsPerf.default 1167 1157 1.01:1
DialogMinimalPerf.default 838 831 1.01:1
DropdownManyItemsPerf.default 775 765 1.01:1
ListMinimalPerf.default 576 571 1.01:1
MenuMinimalPerf.default 961 947 1.01:1
PopupMinimalPerf.default 686 676 1.01:1
SkeletonMinimalPerf.default 392 390 1.01:1
SliderMinimalPerf.default 1842 1830 1.01:1
StatusMinimalPerf.default 758 753 1.01:1
TooltipMinimalPerf.default 1128 1115 1.01:1
AvatarMinimalPerf.default 216 216 1:1
ChatMinimalPerf.default 835 839 1:1
CheckboxMinimalPerf.default 2871 2863 1:1
DropdownMinimalPerf.default 3245 3233 1:1
EmbedMinimalPerf.default 4556 4543 1:1
GridMinimalPerf.default 377 377 1:1
ImageMinimalPerf.default 423 421 1:1
InputMinimalPerf.default 1414 1412 1:1
MenuButtonMinimalPerf.default 1898 1903 1:1
ProviderMinimalPerf.default 1248 1251 1:1
TextMinimalPerf.default 402 400 1:1
ToolbarMinimalPerf.default 1069 1066 1:1
ButtonOverridesMissPerf.default 1808 1834 0.99:1
ButtonSlotsPerf.default 622 629 0.99:1
CarouselMinimalPerf.default 541 548 0.99:1
ChatDuplicateMessagesPerf.default 341 346 0.99:1
RefMinimalPerf.default 253 256 0.99:1
SplitButtonMinimalPerf.default 4788 4847 0.99:1
TableManyItemsPerf.default 2166 2180 0.99:1
TextAreaMinimalPerf.default 576 579 0.99:1
IconMinimalPerf.default 674 690 0.98:1
CustomToolbarPrototype.default 4360 4427 0.98:1
HeaderSlotsPerf.default 841 864 0.97:1
SegmentMinimalPerf.default 382 392 0.97:1
AlertMinimalPerf.default 302 314 0.96:1
RosterPerf.default 1242 1307 0.95:1

@Hotell Hotell marked this pull request as ready for review March 10, 2022 15:29
@Hotell Hotell requested a review from a team as a code owner March 10, 2022 15:29
@fabricteam
Copy link
Collaborator

fabricteam commented Mar 10, 2022

Perf Analysis (@fluentui/react)

No significant results to display.

All results

Scenario Render type Master Ticks PR Ticks Iterations Status
BaseButton mount 1050 1065 5000
Breadcrumb mount 2822 2829 1000
Checkbox mount 1667 1730 5000
CheckboxBase mount 1411 1471 5000
ChoiceGroup mount 5361 5276 5000
ComboBox mount 1104 1092 1000
CommandBar mount 11163 11108 1000
ContextualMenu mount 12136 12237 1000
DefaultButton mount 1274 1294 5000
DetailsRow mount 4223 4261 5000
DetailsRowFast mount 4164 4225 5000
DetailsRowNoStyles mount 4020 3944 5000
Dialog mount 2387 2335 1000
DocumentCardTitle mount 187 196 1000
Dropdown mount 3675 3714 5000
FocusTrapZone mount 1963 1972 5000
FocusZone mount 1956 1908 5000
IconButton mount 2018 2040 5000
Label mount 380 383 5000
Layer mount 3278 3322 5000
Link mount 534 532 5000
MenuButton mount 1688 1715 5000
MessageBar mount 2286 2301 5000
Nav mount 3666 3715 1000
OverflowSet mount 1182 1175 5000
Panel mount 2334 2344 1000
Persona mount 959 935 1000
Pivot mount 1589 1642 1000
PrimaryButton mount 1466 1450 5000
Rating mount 8792 8725 5000
SearchBox mount 1510 1557 5000
Shimmer mount 2799 2790 5000
Slider mount 2134 2148 5000
SpinButton mount 5535 5494 5000
Spinner mount 459 469 5000
SplitButton mount 3497 3536 5000
Stack mount 607 577 5000
StackWithIntrinsicChildren mount 2756 2757 5000
StackWithTextChildren mount 6125 6162 5000
SwatchColorPicker mount 12682 12720 5000
TagPicker mount 3054 3000 5000
TeachingBubble mount 102404 103616 5000
Text mount 492 477 5000
TextField mount 1601 1584 5000
ThemeProvider mount 1273 1286 5000
ThemeProvider virtual-rerender 668 689 5000
ThemeProvider virtual-rerender-with-unmount 2118 2087 5000
Toggle mount 897 897 5000
buttonNative mount 151 143 5000

@@ -216,6 +143,93 @@ const config = {
'operator-assignment': 'off',
'prefer-destructuring': 'off',
'prefer-template': 'off',
// airbnb or other config overrides (some temporary)
// TODO: determine which rules we want to enable, and make needed changes (separate PR)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we want to open a ticket for this right away?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i dunno TBH. as stated in PR I didn't spent extra time to go through every rule rather colocating for better readability. Feel free to investigate further

Copy link
Member

@ecraig12345 ecraig12345 Mar 14, 2022

Choose a reason for hiding this comment

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

This comment is from back when we originally migrated to eslint. The idea back then was to extend the airbnb config (maybe because v0 did?) and eventually enable more rules as we thought it made sense, but we never got around to following up. Since we're disabling so many airbnb rules, it would probably make more sense to just directly enable the rules from there that we do want and remove that config extension (in a separate PR).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this ^ 100%. I'd like us to remove airbnb completely (unmaintaned, loooots of opinionated rules that are not useful that much. I'll work on this as a follow up.

@ling1726
Copy link
Member

I would rename this PR since it seems the main part is adding new rules that weren't there before ?

@Hotell
Copy link
Contributor Author

Hotell commented Mar 10, 2022

I would rename this PR since it seems the main part is adding new rules that weren't there before ?

those rule have been there whole time just turned off, only new rule added is sort-imports.

thoughts?

@Hotell Hotell requested a review from varholak-peter March 10, 2022 18:03
@Hotell Hotell changed the title feat(eslint-plugin): enable autofixable import rules feat(eslint-plugin): add autofixable import rules Mar 10, 2022
@Hotell Hotell force-pushed the hotell/improve-eslint-import-rules branch from 596d38e to cc5df72 Compare March 11, 2022 11:19
Copy link
Contributor

@varholak-peter varholak-peter left a comment

Choose a reason for hiding this comment

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

LGTM 🇴🇲

Copy link
Member

@ecraig12345 ecraig12345 left a comment

Choose a reason for hiding this comment

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

I mentioned this in a comment but I'm still not convinced of the value of having rules which are warning level--unless we have a plan to fix them regularly, it just creates an ever-increasing amount of spam in build logs, and could be confusing for people when they see warnings that are completely unrelated to their change (enabling the rules adds hundreds (edit: thousands) of warnings to the logs).

'no-empty-character-class': 'off',

/**
*
Copy link
Member

Choose a reason for hiding this comment

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

I know this is a picky unimportant thing but all the blank lines starting the comments are bothering me, and IMO it would look nicer to get rid of them

Copy link
Contributor Author

Choose a reason for hiding this comment

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

as you said, not relevant to this PR, we can address as follow up

@@ -216,6 +143,93 @@ const config = {
'operator-assignment': 'off',
'prefer-destructuring': 'off',
'prefer-template': 'off',
// airbnb or other config overrides (some temporary)
// TODO: determine which rules we want to enable, and make needed changes (separate PR)
Copy link
Member

@ecraig12345 ecraig12345 Mar 14, 2022

Choose a reason for hiding this comment

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

This comment is from back when we originally migrated to eslint. The idea back then was to extend the airbnb config (maybe because v0 did?) and eventually enable more rules as we thought it made sense, but we never got around to following up. Since we're disabling so many airbnb rules, it would probably make more sense to just directly enable the rules from there that we do want and remove that config extension (in a separate PR).

@@ -273,15 +313,24 @@ const config = {
* @see https://github.com/import-js/eslint-plugin-import
*/
'import/no-extraneous-dependencies': ['error', { devDependencies: false }],
'import/no-duplicates': 'warn',
Copy link
Member

@ecraig12345 ecraig12345 Mar 14, 2022

Choose a reason for hiding this comment

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

Aren't the new rules going to cause a bunch of spam in build logs due to existing violations? (edit: it adds THOUSANDS of new warnings across all projects. 😱) And I still don't really see the point of even having rules if you can just ignore the warnings (especially since it creates a nuisance for others running lint because they see warnings from code they didn't even touch).

Copy link
Member

Choose a reason for hiding this comment

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

Agree on warnings. They add a lot of noise and not much help. I'd prefer autofix or failing rules only. Otherwise, it probably isn't really a rule if it can't be autofixed or if we can't force the dev to fix it.

@ecraig12345
Copy link
Member

ecraig12345 commented Mar 14, 2022

Have you looked at the overall performance of the lint tasks with and without these rules, and/or whether any of them show up in the top 10 slowest rules when running with timing? You can run with timing by either setting the TIMING environment variable, or passing --timing to just-based eslint tasks. https://eslint.org/docs/developer-guide/working-with-rules#per-rule-performance

Even if there's a significant perf penalty it could still be worth enabling some of the rules, but it would be good to know beforehand what we're signing up for. (In retrospect, I should have asked this on previous PRs adding lint rules too.) In particular I'm wondering if import/no-duplicates was a bit expensive, given that I previously had it disabled in favor of the simpler/"mostly good enough" no-duplicate-imports.

EDIT: I tried running with timing and import/order is sometimes near the top, but deprecation/deprecation is orders of magnitude worse (which is unfortunate, because at least IMO that one does add value).

@ecraig12345
Copy link
Member

ecraig12345 commented Mar 15, 2022

I tried checking out this PR and running eslint with --fix locally...it's modified over 5000 files (meaning there are probably at least 2x that many warnings) including a lot of changes to import ordering that at least to me don't seem like an improvement.

For example:

  • Most of our tsx files have React import as the very first, but now it's moved to/near the end of the list, due to @fluentui imports being interpreted as "external." (This and adding spaces between all groups account for at least half of the changed files.)
  • Right now it's considering @fluentui, @griffel, and @storybook as equivalent externals and lumps them together in a group. @fluentui (and maybe @griffel) ought to be in a slightly different category IMO.

Those issues could be addressed with some further refinements to the config, but there will still be a large number of files with errors.

I also noticed some minor issues with the fixers:

  • The fixer doesn't properly move comments, including // @ts-ignore (which we should almost always avoid anyway...but if we do have them, they need to stay with the proper line)
  • The fixers require multiple passes to get to 0 errors

The following import/order config a bit more closely matches some of the patterns we have now. It's down to "only" 2000+ files (or likely at least 2x that many warnings)...which is still a lot of files to modify, and definitely too many warnings to introduce into everyone's builds if we don't fix them upfront. (I actually like the idea of newlines between groups, but not if it causes an excessive number of warnings that we don't plan to fix upfront.) Here's the config reference--I'm not 100% sure what pathGroupsExcludedImportTypes means or valid values based on the documentation, but the way I used it below seems to be necessary to make the special cases be ordered how I expected.

      {
        alphabetize: {
          order: 'asc',
          caseInsensitive: false,
        },
        groups: ['builtin', 'external', 'parent', 'sibling', 'index', 'type'],
        pathGroups: [
          {
            pattern: '{react,react-dom}',
            group: 'builtin',
            position: 'before',
          },
          {
            pattern: '{@fluentui,@griffel}/**',
            group: 'external',
            position: 'after',
          },
        ],
        pathGroupsExcludedImportTypes: ['{react,react-dom}', '{@fluentui,@griffel}/**'],
      },

All that to say...I agree it would be nice to have more orderly imports, and I'm okay with some version of this PR if we either update it or do a very fast follow-up to get rid of the thousands of warnings. But just introducing thousands of warnings into the build and leaving them there (until someone happens to modify the file again) is not acceptable.

@Hotell
Copy link
Contributor Author

Hotell commented Mar 15, 2022

@ecraig12345

I'm wondering if import/no-duplicates was a bit expensive

I don't follow, this PR is not enabling that rule UPDATE: sorry i miss-read ( it was supposed to be deprecation/deprecation) sorry about that.

Have you looked at the overall performance of the lint tasks with and without these rules

Thanks for bringing this up. I have. it's not the best but it's worth the cost from my experience. Any rule needing type information is far worse than this. Also rules from import plugin are problematic in general in terms of performance. Is there valid business case to re-implement those rules on our own and maintain those ? I don't think so ATM.

Most of our tsx files have React import as the very first, but now it's moved to/near the end of the list, due to @FluentUI imports being interpreted as "external." (This and adding spaces between all groups account for at least half of the changed files.)

That's fine from my experience. What is first or second doesn't improve our code, nor provides any benefit to consumers. Aim is to have consistency without need to nit-picking on peoples work based on "particular reviewer opinion"

pathGroups: [ {

This will need to be manually maintained if we add/change something else. is it worth it ? From my experience it is not. If majority of folks agree, then let's update it and maintain it. The argument of having "less warnings" at the moment will be mitigated soon as I mention at the end of this long comment.

And I still don't really see the point of even having rules if you can just ignore the warnings

I'd say this is out of topic for this PR and we can discuss this in bigger quorum.

Also note I explicitly stated in PR description following:
image

To provide brief context, based on my experience, having linting errors just increases anxiety for any contributor during pressing keystroke.

lint errors are justified only for things that:

  • may cause security vulnerability
  • may cause runtime errors
  • may cause serious performance hits

Anything else is mostly just unnecessary churn, thus having it as warning that is autofixable ( thus will be fixed anyways during commit ) is very pleasant DX/low effort from contributor to follow.

Actionables:

  • the idea is that as we did multiple times already, every team will apply those fixes in their components

Tooling constrains:

Because eslint doesn't provide gradual rule application, to mitigate this we have only 2 options:

  • add these rule package by package + apply fixes
    • you cannot measure/track this approach in any way (current approach gives you explicit data)
  • enable quite mode, so warning are not logged on CI
    • again you cannot measure/track this approach

None of these approaches will move us to 1 goal - have all things consistently formatted

To summarize: In general I wanna address existing issues, linked in this PR, that devs are facing on daily basis. 2 members of tooling team approved. Lemme know how do you wanna proceed @ecraig12345 based on additional options I provided.

thanks

@GeoffCoxMSFT
Copy link
Member

@Hotell Would this PR be a good thing to cover in tech sync? It might be nice to get some team-wide input and awareness if this does introduce a large set of warnings to go fix. You fanned out the work items so nicely with the ts solution fixes - maybe that should happen again here?

@GeoffCoxMSFT
Copy link
Member

@Hotell If warnings are fixed as part of saving in vscode, could we run a nx script to run the es-lint formatter across all the files in a package and basically do a save of every file on behalf of the user?

@ecraig12345
Copy link
Member

If warnings are fixed as part of saving in vscode, could we run a nx script to run the es-lint formatter across all the files in a package and basically do a save of every file on behalf of the user?

It's simpler than that--eslint has a --fix option, so you can either run yarn lint --fix in an individual package, or yarn lage lint --fix for the whole repo. (In either case you may need two passes to ensure everything is fixed.)

@ecraig12345
Copy link
Member

I like the idea of more orderly imports, but here's my main concern with the current approach: unless we fix all the new "issues" immediately, this PR will introduce a substantial amount of confusion/extra mental load for all developers in our repo:

  • It becomes much harder to find actual lint errors or other build errors, in either a PR or local build, due to the sea of lint warnings.
  • It will create confusion/demand extra mental energy from developers (especially outside the core team who don't know about this change), possibly at multiple points in the process:
    • Anyone editing a file will see a bunch of things that appear to be unresolved issues sitting there, which can require extra mental energy to evaluate whether they need to address or not.
      • The warnings will disappear on save or commit, but then there's confusion about "why did my commit touch all these unrelated lines."
    • It's likely that developers will be confused when their PR or local build is suddenly be filled with warnings, and whether they need to do anything about that.

This is a substantial cost to impose on everyone, so I'd like to get agreement from the team about whether it's worth it. Both of the linked issues are ones you made, so it's not clear from that what the priority is from other people. (It's also not clear if the other reviewers realized just how many warnings this would cause.)


For specific points:

I'm wondering if import/no-duplicates was a bit expensive

I don't follow, this PR is not enabling that rule

Yes it is, as warnings
https://github.com/microsoft/fluentui/pull/22050/files#diff-76039af2f09c079049956d7b4b45efee6d01993677e1680519f5863fae6f0919R316

Have you looked at the overall performance of the lint tasks with and without these rules

Thanks for bringing this up. I have. it's not the best but it's worth the cost from my experience. Any rule needing type information is far worse than this. Also rules from import plugin are problematic in general in terms of performance. Is there valid business case to re-implement those rules on our own and maintain those ? I don't think so ATM.

I edited my comment about this since I tested it and it turned out the perf concern from these rules isn't too bad, particularly compared to the deprecation rule. I never proposed re-implementing any import rules (I only did that for max-len based on specific data), just advocating understanding the cost vs. benefits before we enable new rules.

Most of our tsx files have React import as the very first, but now it's moved to/near the end of the list, due to @fluentui imports being interpreted as "external." (This and adding spaces between all groups account for at least half of the changed files.)

That's fine from my experience. What is first or second doesn't improve our code, nor provides any benefit to consumers. Aim is to have consistency without need to nit-picking on peoples work based on "particular reviewer opinion"

I agree the most important thing is automating it, but the default behavior of the rule itself acknowledges that there can be some value (even if it's minor) from "logical" grouping of imports: by default, ["builtin", "external", "parent", "sibling", "index"]. The order I proposed is a natural extension of the default order for our context, and aligns with conventions that are already widely used within our repo. (I could go either way on whether to have separate ordering for type imports.)

pathGroups: [ {

This will need to be manually maintained if we add/change something else. is it worth it ? From my experience it is not. If majority of folks agree, then let's update it and maintain it. The argument of having "less warnings" at the moment will be mitigated soon as I mention at the end of this long comment.

This shouldn't require maintenance. The only exceptions are for our primary component scope (I could go either way about whether to special-case griffel), and packages from our core library, so unless we rename our scope again it won't be an issue.

To provide brief context, based on my experience, having linting errors just increases anxiety for any contributor during pressing keystroke.

As outlined above, my concern is adding so many warnings will have the same effect, and worse.

Actionables:

  • the idea is that as we did multiple times already, every team will apply those fixes in their components

At least to me, this is a bit different than the previous times we've applied that approach (which I'm still not a fan of to begin with, at least if it involves separate PRs for every package). This is forcing a pretty severe load of extra noise on everyone until the fixes are made.

Tooling constrains:

Because eslint doesn't provide gradual rule application, to mitigate this we have only 2 options:

  • add these rule package by package + apply fixes

    • you cannot measure/track this approach in any way (current approach gives you explicit data)

If you don't want to do the changes all at once, we can track it with issues, same as we have before.

  • enable quite mode, so warning are not logged on CI

    • again you cannot measure/track this approach

None of these approaches will move us to 1 goal - have all things consistently formatted

To summarize: In general I wanna address existing issues, linked in this PR, that devs are facing on daily basis. 2 members of tooling team approved. Lemme know how do you wanna proceed @ecraig12345 based on additional options I provided.

As mentioned above, it's not clear the level of priority this goal has for the team at large, and whether people consider it worth the tradeoff of having so many warnings.

@ecraig12345
Copy link
Member

ecraig12345 commented Mar 16, 2022

Made an issue for separate v8/v9 eslint configs - #22127. As discussed in the meeting, I'm more okay with this if it's enabled for v9 only, we just don't have a good way to do that right now since v8/v9 share a config.

@levithomason
Copy link
Member

I second a lot of what @ecraig12345 is raising. Simple is better than complex. This applies to the rule system as well as the dev experience. We should guard the number of cycles a dev has to spend and the number of cycles the build has to spend.

⚠️ Let's not flood warnings as it removes the usefulness of the rule. People ignore things that flood since it is overwhelming.

🛑 Either fail or autofix the rule. Let's no require devs to think more than the bare minimum. They should focus on writing great code.


All said, I don't think sorting imports is worth the cost to setup, maintain, and execute compared to the benefit it provides. We have a lot of high impact work that I'd love to see our energy going into instead. I will leave it at that and go with what the team decides.

@Hotell
Copy link
Contributor Author

Hotell commented Mar 16, 2022

@levithomason

I second a lot of what @ecraig12345 is raising. Simple is better than complex. This applies to the rule system as well as the dev experience. We should guard the number of cycles a dev has to spend and the number of cycles the build has to spend.

⚠️ Let's not flood warnings as it removes the usefulness of the rule. People ignore things that flood since it is overwhelming.

🛑 Either fail or autofix the rule. Let's no require devs to think more than the bare minimum. They should focus on writing great code.

All said, I don't think sorting imports is worth the cost to setup, maintain, and execute compared to the benefit it provides. We have a lot of high impact work that I'd love to see our energy going into instead. I will leave it at that and go with what the team decides.

From your response it feels like you didn't read my reasoning, nor the PR description with live demos, can you help me understand if thats the case ?

Let's not flood warnings as it removes the usefulness of the rule.

warnings will disappear in time as people touch files ( everything is handled automatically ), which is also a good metric on progress. Goal should be to get rid of this.

All said, I don't think sorting imports is worth the cost to setup, maintain, and execute compared to the benefit it provides.

It would be helpful to elaborate on what do you mean by "cost to setup", the cost of this setting up took me 20 seconds.

Those rules are autofixable, so what are you referring to ?

They should focus on writing great code.

this is the main goal of the tooling we are adding, as I mentioned during sync, focus on what consumer are getting not what is formatted how. I don't understand where do you see this approach as going against that mantra ?

I will leave it at that and go with what the team decides.

as mentioned during sync and via referenced issues, This PR was created on real feedback from core framework devs

@Hotell
Copy link
Contributor Author

Hotell commented Mar 16, 2022

based on discussion in this PR, it turns out we don't have common consensus.

Following PR #22128, fixes inheritance issues with our current lint setup and adds new imports config which particular teams can opt into, to leverage autofixable imports, as they see fit, to address issues linked in this PR that triggered these changes in first place.

In the future, we might open this topic again, or as a followup if we see major adoption of autofixable import rules within v9 packages.

@Hotell Hotell closed this Mar 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat(eslint): prevent duplicate module import paths lint: add imports auto/alphabetical ordering
9 participants