eslint-react icon indicating copy to clipboard operation
eslint-react copied to clipboard

[feat] Sort key before spread

Open remcohaszing opened this issue 8 months ago • 1 comments

Describe the problem

There are already rules to sort props.

These are stylistic rules. So they rightfully don’t sort props before or after prop spread syntax. However, when using the JSX automatic runtime, key is a special attribute in the JSX transform. See the Babel repl and TypeScript playground

If the key prop is before any spread props, it is passed as the key argument of the _jsx / _jsxs / _jsxDev function. But if the key prop is after spread props, The compiler uses createElement instead and passes key as a regular prop.

Describe the solution you'd like

It would be useful to have a rule that warns the user if the key prop appears after JSX spread syntax.

Alternatives considered

It could also be incorporated into @eslint-react/no-implicit-key.

Additional context

The key doesn’t have to be first, only before JSX spread syntax. Other rules can take care of sorting.

remcohaszing avatar Apr 17 '25 15:04 remcohaszing

This feature request has been accepted, I will add a jsx-key-before-spread rule.

Rel1cx avatar Apr 20 '25 05:04 Rel1cx

Hmm... Why not just port jsx-sort-props directly?

JounQin avatar May 05 '25 09:05 JounQin

There are already multiple rules to sort props. These correctly allow users to sort props before or after JSX spread syntax. This is important, because spread syntax changes the order in which the props override each other. The key prop is a special case. Its meaning changes depending on whether or not it appears after JSX spread syntax.

remcohaszing avatar May 05 '25 10:05 remcohaszing

Then why it must be implemented here instead of an option of perfectionist/sort-jsx-props nor @stylistic/jsx/jsx-sort-props?

JounQin avatar May 05 '25 10:05 JounQin

Then why it must be implemented here instead of an option of perfectionist/sort-jsx-props nor @stylistic/jsx/jsx-sort-props?

Because this is the only way to correctly set the severity of the two types of problems mentioned above under the ESLint plugin system, which allows setting jsx-key-before-spread to error, jsx-sort-props to warn, or setting jsx-key-before-spread to warn and override jsx-sort-props to info in the editor (via "eslint.rules.customizations"). And be able to correctly disable each of them in different contexts via eslint-disable comments.

Rel1cx avatar May 05 '25 11:05 Rel1cx

Because this is the only way to correctly set the severity of the two types of problems mentioned above under the ESLint plugin system

Why it/they should be considered two types of problems at the first place? There are many rules have different options, and different options share same severity, we don't provide different rules for each of them only for different severities?

JounQin avatar May 05 '25 12:05 JounQin

Because this is the only way to correctly set the severity of the two types of problems mentioned above under the ESLint plugin system

Why it/they should be considered two types of problems at the first place? There are many rules have different options, and different options share same severity, we don't provide different rules for each of them only for different severities?

This is exactly the bad practice, caused by a lack of understanding of the linter tool.

Rel1cx avatar May 05 '25 12:05 Rel1cx

This is exactly the bad practice, caused by a lack of understanding of the linter tool.

Hah? The current implementation is exactly the bad practice without cooperations with other plugins IMO. But well, you're the boss here.

JounQin avatar May 05 '25 12:05 JounQin

This is exactly the bad practice, caused by a lack of understanding of the linter tool.

Hah? The current implementation is exactly the bad practice without cooperations with other plugins IMO. But well, you're the boss here.

The project was created with the philosophy of "Rules Over Options", and many of the achievements made so far have benefited from this choice.

Rel1cx avatar May 05 '25 12:05 Rel1cx

This is exactly the bad practice, caused by a lack of understanding of the linter tool.

Hah? The current implementation is exactly the bad practice without cooperations with other plugins IMO. But well, you're the boss here.

The current implementation is exactly the bad practice without cooperations with other plugins IMO.

Each rule should have a single purpose. Make multiple rules work together to achieve more complex behaviors instead of adding endless options to a single rule. IMO, This is how plugins should cooperate.

Rel1cx avatar May 05 '25 12:05 Rel1cx

The project was created with the philosophy of "Rules Over Options", and many of the achievements made so far have benefited from this choice.

That's exactly what I mean "you're the boss here", you can have your own philosophy, that's totally fine, although anyone else like me might disagree.

JounQin avatar May 05 '25 14:05 JounQin

Each rule should have a single purpose. Make multiple rules work together to achieve more complex behaviors instead of adding endless options to a single rule.

AKA "composition over configuration" 💯

merrywhether avatar May 05 '25 16:05 merrywhether

AKA "composition over configuration" 💯

It's definitely not, every single rule needs to be enabled specifically. 😅

JounQin avatar May 05 '25 16:05 JounQin

In most cases, this is an advantage rather than a drawback. When a rule takes on too many responsibilities, the rule itself becomes a "plugin", and its error messages (as well as options) act as the actual "rule". However, in the ESLint plugin system and configuration system, error messages (and options) are not first-class citizens (this includes their inability to set different severity levels based on the actual situation, and their inability to independently control through the use of eslint-disable/enable comments, and more...), but rules are.

A typical bad example is solid/reactivity.

Rel1cx avatar May 05 '25 21:05 Rel1cx