You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ESLint v9's flat config migration (#191, merged in #204) left several packages in an inconsistent state: rule formats weren't normalized across eslint-config-react/typescript/jest, and eslint-config-base never fully absorbed eslint-config-airbnb-base — 37 of its style rules were silently dropped, one rule (no-mixed-operators) had a corrupted value that crashes ESLint v9 outright under strict schema validation, and whitespace.js still depended on the real eslint-config-airbnb-base package through a FlatCompat shim that wasn't even a declared dependency. None of the eslint-config-* packages had any test coverage, so none of this was caught automatically.
This PR normalizes the flat-config format across the affected packages, then makes eslint-config-base a complete, self-contained superset of airbnb-base: restores the missing style rules with airbnb's exact values, fixes the crash-causing rule, and rewrites whitespace.js as a small pure function that derives its rule set directly from the package's own rule files instead of the external package. It also adds the package's first test suite (node --test, matching the pattern already used by stylelint-config), covering the base config's airbnb inheritance and ALMA overrides, legacy.js's ES5/strict-mode behavior, optional.js's extra rules, and whitespace.js's severity-downgrade logic.
Additional context
style.js still has ~15 pre-existing no-dupe-keys lint findings (a rule is listed once under the airbnb section and again under the ALMA override section) — valid JS, flagged by the repo's own lint, left as-is pending a decision on whether to clean it up separately.
Several restored rules (e.g. indent, no-tabs) are marked deprecated upstream per eslint/eslint#17522 — they still work today but ESLint may drop them in a future major; worth revisiting if/when that happens.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🟡 Changes recommended
Several rule overrides drop required/meaningful options (changing behavior unexpectedly), and the base legacy config references an invalid node/no-process-env rule ID that can break ESLint config loading.
Get a fresh assessment by requesting another Copilot review.
This PR completes the ESLint v9 flat-config migration across the repo’s eslint-config-* packages, with a focus on making @alma-oss/eslint-config-base fully self-contained (no longer relying on eslint-config-airbnb-base via FlatCompat) while restoring Airbnb Base rule parity and adding initial automated tests for the base package.
Changes:
Rebuilds eslint-config-base as a self-contained flat config by inlining Airbnb Base rules into local rules/* modules and rewriting legacy.js/whitespace.js without FlatCompat.
Normalizes/updates config formatting across React/TypeScript/Jest packages (including @eslint/compat usage where still extending external configs).
Adds a Node test suite (node --test) for eslint-config-base plus fixtures, and updates repo-level ignore rules for fixtures.
The reason will be displayed to describe this comment to others. Learn more.
Copilot review overview
🔵 Needs a closer look
It contains config/test correctness issues (invalid rule key in legacy config, lost arrow-body-style option, and “valid” fixtures that will trigger warnings) that can break consumers and/or fail the new test suite.
This legacy fixture includes padded blank lines inside the function body, which will trigger padded-blocks and cause the test’s “no warnings” assertion to fail.
Remove padded blank lines from the function fixture
This fixture currently contains padded blank lines inside the function body, which will trigger padded-blocks (configured in the base style rules). The test expects 0 warnings, so the fixture should avoid padding inside blocks.
This issue also appears on line 7 of the same file.
Set FlatCompat baseDirectory for package-relative resolution
packages/eslint-config-react/index.js:5
FlatCompat defaults to resolving extends/plugins relative to process.cwd(). That can break consumers depending on where ESLint is executed (monorepos, editors, etc.). Set baseDirectory so compat.extends(...) resolves relative to this package.
Set baseDirectory for Airbnb config resolution
packages/eslint-config-react/whitespace.js:5
Same FlatCompat resolution issue here: without baseDirectory, compat.extends('eslint-config-airbnb/whitespace') is resolved relative to the caller’s working directory rather than this package, which can make the config fragile for consumers.
* groups array had a duplicate '^' entry and was missing the
'<<', '>>', '>>>' bitwise operators
* eslint v9's stricter schema validation throws on the duplicate
item, making the whole config uninstantiable
* also restored the '==','!=','===','!==' and '&&','||' groups
that airbnb-base defines but were missing entirely
* 37 style.js rules existed in eslint-config-airbnb-base but were
silently dropped during the v9 migration, changing behavior for
anything relying on full airbnb parity
* restored them with airbnb's exact values, including
deprecated-but-functional formatting rules like indent and
no-tabs, per the decision to keep eslint-config-base a faithful
superset rather than pre-emptively deferring to prettier
* whitespace.js depended on FlatCompat + the real
eslint-config-airbnb-base package via @eslint/eslintrc, which
wasn't a declared dependency anywhere and only resolved by
accident through hoisting
* replaced it with a small pure function that derives the same
error-only-on-whitespace-rules transform directly from our own
rule files, so it can never drift from the rest of the config
and needs no external deps or legacy compat shims
…and whitespace configs
* none of the eslint-config-* packages had any tests, so a rule
regression (like the no-mixed-operators crash found earlier)
could ship silently
* covers all four entry points: the base config's airbnb
inheritance and ALMA overrides, legacy's ES5/strict-mode
requirement, optional's extra rules, and whitespace's
error-only-on-whitespace-rules transform
* added a 'test' script so lerna run test actually picks the
package up
* the new fixtures are deliberately invalid/non-standard js, so
the repo's own strict self-lint flagged them as violations
* the existing ignores entry couldn't do this globally because it
shared an object with rules/settings, which in flat config only
scopes that config's own rules rather than excluding files
repo-wide - added a standalone ignores-only entry
* no-multi-str and no-useless-escape were defined in both
best-practices.js and style.js with identical values, dead
redundancy left over from restoring the missing style rules
* airbnb-base itself only defines these two rules in
best-practices.js, so this wasn't inherited duplication - removed
the style.js copies and kept best-practices.js as the single
source of truth
The reason will be displayed to describe this comment to others. Learn more.
This one was valid.
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
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.
Description
ESLint v9's flat config migration (#191, merged in #204) left several packages in an inconsistent state: rule formats weren't normalized across eslint-config-react/typescript/jest, and eslint-config-base never fully absorbed eslint-config-airbnb-base — 37 of its style rules were silently dropped, one rule (
no-mixed-operators) had a corrupted value that crashes ESLint v9 outright under strict schema validation, andwhitespace.jsstill depended on the realeslint-config-airbnb-basepackage through aFlatCompatshim that wasn't even a declared dependency. None of theeslint-config-*packages had any test coverage, so none of this was caught automatically.This PR normalizes the flat-config format across the affected packages, then makes
eslint-config-basea complete, self-contained superset of airbnb-base: restores the missing style rules with airbnb's exact values, fixes the crash-causing rule, and rewriteswhitespace.jsas a small pure function that derives its rule set directly from the package's own rule files instead of the external package. It also adds the package's first test suite (node --test, matching the pattern already used bystylelint-config), covering the base config's airbnb inheritance and ALMA overrides,legacy.js's ES5/strict-mode behavior,optional.js's extra rules, andwhitespace.js's severity-downgrade logic.Additional context
style.jsstill has ~15 pre-existingno-dupe-keyslint findings (a rule is listed once under the airbnb section and again under the ALMA override section) — valid JS, flagged by the repo's own lint, left as-is pending a decision on whether to clean it up separately.indent,no-tabs) are marked deprecated upstream per eslint/eslint#17522 — they still work today but ESLint may drop them in a future major; worth revisiting if/when that happens.Related issues
Relates to #191