Skip to content

[main] Align the ESLint ruleset with the Kaoto project #115

Description

@lordrip

Target branch: main (currently v2.2.0).
The equivalent change for the 1.x maintenance line is tracked separately.
eslint.config.mjs is byte-identical on both branches, so the rule delta below
applies verbatim to each.

Motivation

eslint.config.mjs here is an early fork of Kaoto's and has since drifted. Kaoto
has added import sorting, type-aware rules and a set of React/JSX rules — several
of them adopted specifically to satisfy SonarQube rules that also apply to this
repo. Code moving between the two repositories currently fails lint in one
direction or the other.

Additional problem: lint never actually runs here

package.json defines no lint script, and the root has no workspaces
field — yet .github/workflows/build-publish.yaml runs:

yarn workspaces foreach --verbose --all --topological-dev run lint

so the "💅 Run eslint" CI step has nothing to execute. A .stylelintrc exists
with no lint:style script either.

Scope

1. Add the missing scripts (mirroring Kaoto's packages/ui)

"lint": "yarn eslint \"src/**/*.{ts,tsx}\"",
"lint:fix": "yarn lint --fix",
"lint:style": "yarn stylelint \"src/**/*.{css,scss}\"",
"lint:style:fix": "yarn lint:style --fix"

and change the CI step to yarn lint (the workspaces foreach form does not
apply to this single-package repo).

2. Add the missing dev dependencies

  • eslint-plugin-simple-import-sort
  • eslint-plugin-testing-library
  • @vitest/eslint-plugin

3. Adopt the rule delta

Currently missing relative to KaotoIO/kaoto's root eslint.config.mjs:

TypeScript (type-aware — requires parserOptions.project scoped to src/**/*.{ts,tsx})

  • @typescript-eslint/prefer-readonly (SonarQube typescript:S2933)
  • @typescript-eslint/no-floating-promises
  • @typescript-eslint/no-confusing-void-expression

Imports

  • simple-import-sort/imports
  • simple-import-sort/exports

React / JSX

  • react/jsx-boolean-value: ['error', 'never']
  • react/jsx-curly-brace-presence: ['error', { props: 'never', children: 'never' }]
  • react/no-unstable-nested-components
  • react/function-component-definition (arrow functions for named and unnamed)
  • react/jsx-no-useless-fragment: ['error', { allowExpressions: true }]
  • react/self-closing-comp
  • settings.react.version: 'detect'

Test files (**/*.test.{ts,tsx}) — depends on the Vitest migration:

  • vitest/prefer-to-have-length, vitest/prefer-to-be (SonarQube typescript:S5906)
  • testing-library/no-unnecessary-act (SonarQube typescript:S8980)

4. Review the config ordering

This repo places eslintConfigPrettier / eslintPluginPrettier before the React
rules block; Kaoto places them last. In flat config the later entry wins, so the
current ordering may let React rules override Prettier's formatting opt-outs. Verify
whether this changes any output, and if so move them to the end to match Kaoto.

Dependency

The three test-file rules require Vitest, so land them after (or together with) the
Jest → Vitest migration for this branch. Everything else can go in independently.

Acceptance criteria

  • yarn lint and yarn lint:style exist and pass on a clean tree
  • CI actually executes the lint step and fails on violations
  • eslint.config.mjs is rule-for-rule equivalent to Kaoto's root config, plus the test-file overlay from packages/ui/eslint.config.mjs

Reference

  • KaotoIO/kaoto@eslint.config.mjs (root) and packages/ui/eslint.config.mjs
  • Relevant Kaoto commits: 654feb4 (simple-import-sort), d8ff9ac (no-floating-promises),
    278a96d (prefer-readonly + tsconfig), eb5c3f9 (stricter React/JSX),
    b95f039 / 339383a (S5906), 9619793 (no-unnecessary-act)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions