Switch ui/ linting from eslint to biome#8680
Open
Eijebong wants to merge 24 commits into
Open
Conversation
Eslint's ecosystem has been very unmaintained for quite some time, it brings in a lot of dependency that have open CVEs and despite those not affecting us in a way that matters, they're noisy and are hard to trace back to the linter. On top of that, eslint is *slow*, the config is quite arduous to migrate over newer versions. Instead of paying the price of that when updating to the latest we could update to (which would be one or two major version out of date since we have dependencies on unmaintained eslint plugins that don't support the latest versions), switch to biome. I've already found and fixed a few bugs due to some of the lints that biome has that eslint didn't. Biome is also faster (especially on first runs). Regarding the config, I kept it fairly simple, enabling the recommended lints and disabling those that were giving false positives without providing extra value: - `useNodejsImportProtocol`: we polyfill things so this is all false positives I also tried matching the formatter to our prettier config as best I could although there's some differences that I couldn't avoid. Note that while I said in 70b691a that this work should allow us to remove the `get-intrinsic` resolution, it turns out that nope, it cannot. Webpack-cli also brings in v8-compile-cache which makes it fail in the same way. So we have to keep the resolution until webpack is either updated or gone.
This formats the UI code with biome instead of prettier. Most of the changes are because prettier really didn't like destructuring objects on one line even if the lines wasn't going over the line size limit and because biome really wants `() =>` to be on its own line. There's no config option to match those between prettier/biome so we have to eat the difference.
This applies all fixes that biome considers safe. (`noUselessThisAlias`, `noPrototypeBuiltins`, `useRegexLiterals`). Those are all very tiny changes so I decided to bundle them together in the same commit.
Biome complains about `useExhaustiveDependencies` in two places where the dependency list for `useEffect` is not evident. They're both safe to ignore.
This is just a translation of `eslint-disable` to `biome-ignore`.
This renames a bunch of function parameters by prepending a `_` to them. I've checked them all and they're all legitimately unused.
The `match?.params` here (added back in 1372614) would crash if `match` was actually undefined as it'd resolve to `const { taskId } = undefined`. In practice, `match` is always provided by `react-router` *and* we already use it unconditionally on line 24: `taskId: props.match.params.taskId`. Since it's useless, just remove the optional chaining to make biome happy.
In practice this is going to make no difference whatsoever. But biome calls it out because in theory you could get an array from a different domain (an iframe), which would get checked against the Array prototype of the current domain and differ. In this case, that's never going to happen, but this follows what MDN [recommends](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#instanceof_vs._array.isarray), works, and silences a biome warning.
Biome is a bit too trigger happy on this lint and complains about our JSON-e since it's creating objects with a `then` property which could indeed be a problem later on if those were thenable. Since they're static objects that get resolved and never get awaited, we don't care and they're safe to ignore.
Biome was complaining that the `<Link>` side of the ternary was missing
a `key` (rightfully so). The other branch already had a
`key={indexName}` but while testing this I realized that having an index
path like: `foo.foo.foo` would duplicate keys in the breadcrumb which
should lead to react being unhappy with us and emitting warnings. It
turned out in practice not to be an issue because the component is used
in a breadcrumb which rewrites the `key` anyway to `child-{i}`. I
switched the key on both sides anyway to `{path}` which is guaranteed to
be unique and stable. It fixes the warning and will avoid someone else
getting tripped by this as well as stop depending on an internal MUI
behavior for this to be correct.
Biome flagged the `toString` import from ramda as shadowing the global `toString`. The import was only used to produce a stable key for a React `<Fragment>`, which I just replaced with `JSON.stringify(scope)` which basically does the same thing. This drops the ramda import and silences the warning.
There were 4 reduces that were copying the accumulator content in reduce on each step instead of mutating it which made it `O(n^2)` instead of `O(n)`. I'm not expecting any of these to make a real world performance difference but this is the same, is faster and silences biome.
It provides no value on the page and is just cosmetic. Fixes a `a11y/noSvgWithoutTitle` biome lint tripup.
This fixes a biome `a11y/noSvgWithoutTitle` lint. I don't think "Trend graph" is a great title, but the alternatives are marking those as `aria-hidden` or threading in the title of the graph which has no real upside since the SVG content is not describable anyway. I chose to keep the title because I think it's confusing to get "Last 24h" -> *Nothing* instead of "Last 24h" -> "Trend graph" but I'm by no mean an accessibility expert and would be ok with changing that, should anyone voice any concern.
This fixes 2 lints regarding accessibility on this element, `a11y/useSemanticElements` and `a11y/useKeyWithClickEvents`. The result looks exactly the same and now works with keyboard navigation
The alt is provided through props. We could technically add it as a prop, destructure props with a default of `''` for alt and use that, but that means that an image with no alt would end up with `alt = ""` which I don't think is better. So just keep the previous behavior and silence the lint.
It provides no value on the page and is just cosmetic. Fixes a `a11y/noSvgWithoutTitle` biome lint.
Switch the `desc` to a `title` which pretty much does the same (`title` is mandatory, `desc` can be used to describe more if needed)
Biome flags the bars as being static elements with a hover/click but not having keyboard interactions. Making those keyboard interactable means marking each bar as a button + tabIndex which means keyboard navigation would require pressing tab 200+ times to get past the graph which is way worse than not being able to interact with the graph. Especially given the tasks are accessible below.
Since we're using virtualization here we can't use a proper `<table>` element which biome gets angry about. This is a virtualization issue and we make this accessible by setting the role manually instead of using the "right" element. Just ignore the lint.
This matches the old eslint config
This isn't enabled by default so enable it and mark the various calls as ignored.
This finalizes the migration from eslint to biome. There's a lot of removed annotations in here that don't have a matching biome rule. However, some of these were already not exercised by eslint since the migration off of neutrino, and the remaining ones are not in biome because they're only valid with old versions of react. Updating to biome is part of my journey towards getting us to a more recent set of dependency, so let's accept the gap for now. Some of these lints are also superseded by the formatter or opinionated choices made by eslint.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This should be reviewed commit by commit. I tried keeping lint fixes split up and justified.
Note that a lot of issues discovered during this migration have already been merged, the fixes in here are tiny enough that I didn't feel like they warranted their own PR.
The first commit does the scaffolding, switches eslint to biome with a configuration that matches somewhat. The two commits after that are autogenerated with biome. Each commit after that fixes/silences specific lints.
Part of #8372, doesn't close it yet as we're still using eslint in services/clients.