Skip to content

chore: prepare for ESLint 10 more - #458

Merged
SukkaW merged 23 commits into
un-ts:masterfrom
SukkaW:eslint-10-2
Mar 11, 2026
Merged

SukkaW merged 23 commits into
un-ts:masterfrom
SukkaW:eslint-10-2

Conversation

@SukkaW

@SukkaW SukkaW commented Feb 22, 2026 •

Copy link
Copy Markdown
Collaborator

Another step toward #438.

  • Added ESLint 10 to the CI matrix
  • Increase @typescript-eslint/utils peerDeps range to 8.56.0, which also ensures our end-users won't face issues with ESLint 10.
  • Bump a few devDeps to the current latest version
    • @typescript-eslint/parser, @typescript-eslint/rule-tester, and @typescript-eslint/utils: fixes ESLint 10
  • Fixed a few test cases
    • With the latest @typescript-eslint/parser, we are facing A type-only import can specify a default import or named bindings, but not both. error. I fixed it by using the NBabel ESLint parser in those tests.
    • LegacyESLint has been removed, only tests cli.spec.ts with ESLint 9 for now
    • Skip no-unused-modules tests for ESLint 10 for now, proper fix is in refactor: make no-unused-modules no-op on ESLint 10 or later #457

Important

Prepare for ESLint 10 by updating dependencies and adjusting tests for compatibility.

  • CI:
    • Add ESLint 10 to CI matrix in ci.yml.
  • Dependencies:
    • Update @typescript-eslint/utils peer dependency to ^8.56.0 in package.json.
    • Update devDependencies: @babel/eslint-parser, @typescript-eslint/parser, @typescript-eslint/rule-tester, @typescript-eslint/utils to ^8.56.0.
  • Tests:
    • Fix test cases in no-empty-named-blocks.spec.ts and order.spec.ts by using Babel parser for type-only import errors.
    • Skip no-unused-modules tests for ESLint 10 in no-unused-modules.spec.ts.
    • Remove LegacyESLint usage in cli.spec.ts and test cli.spec.ts with ESLint 9 only.

This description was created by Ellipsis for 5138a48. You can customize this summary. It will automatically update as commits are pushed.

Summary by CodeRabbit

  • Chores

    • Added ESLint 10 support across CI and package config, added an eslint10 alias, and pinned Node.js to 20.19 in CI.
    • Updated multiple ESLint-related tooling and TypeScript-ESLint versions.
    • Improved handling of missing default options to avoid errors.
    • Added a changeset recording the peer-dependency range update.
  • Tests

    • Updated tests to adjust parser configuration and ESLint-version constraints to match the updated tooling.

@SukkaW
SukkaW requested a review from Copilot February 22, 2026 19:15
@changeset-bot

changeset-bot Bot commented Feb 22, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 26bee1e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
eslint-plugin-import-x Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@SukkaW
SukkaW requested a review from 43081j February 22, 2026 19:15
@coderabbitai

coderabbitai Bot commented Feb 22, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds ESLint 10 to CI and dependencies, updates Node in CI, upgrades many @typescript-eslint and ESLint-related packages, makes applyDefault accept undefined defaults, relaxes typings for an ESLint internal import, adjusts several tests for parser/ESLint-version constraints, and adds a changeset.

Changes

Cohort / File(s) Summary
CI
.github/workflows/ci.yml
Adds eslint v10 to the CI matrix, bumps Node to 20.19, excludes ESLint10 on Node18, and conditionally installs @babel/eslint-parser for ESLint 10.
Package manifest
package.json
Expands ESLint peer range to include v10, adds eslint10 alias, and upgrades numerous @typescript-eslint/*, @babel/eslint-parser, devDependencies, and resolutions.
Core utility
src/utils/apply-default.ts
Function signature now accepts `defaultOptions: Readonly
Rule typing adjustment
src/rules/no-unused-modules.ts
Casts imported ESLint internal API to any to allow destructuring FileEnumerator and shouldUseFlatConfig without TypeScript errors; runtime behavior unchanged.
Tests — parser / ESLint-constraint updates
test/cli.spec.ts, test/rules/no-empty-named-blocks.spec.ts, test/rules/order.spec.ts, test/rules/no-unused-modules.spec.ts
Changes test import to eslint9/use-at-your-own-risk, adds languageOptions (Babel parser) for specific TS parse cases, and constrains rule-tester ESLint range (<10.0.0) where needed.
Changeset
.changeset/hungry-owls-start.md
Adds a changeset declaring a patch bump and noting updated peer dependency range to support ESLint 10.

Sequence Diagram(s)

(Skipped — changes are dependency, test, and typing adjustments without new multi-component control flow.)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

dependencies, internal

Suggested reviewers

  • JounQin
  • 43081j

Poem

🐰 Hop, hop — versions climb a tree,

ESLint ten peeks out to see.
Defaults wake when optional called,
Tests don new caps, typings softened, all.
🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'chore: prepare for ESLint 10 more' clearly summarizes the main change: continuing preparation for ESLint 10 compatibility through CI updates, dependency bumps, and test adjustments.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Important

Looks good to me! 👍

Reviewed everything up to 5138a48 in 15 seconds. Click for details.
  • Reviewed 174 lines of code in 7 files
  • Skipped 1 files when reviewing.
  • Skipped posting 0 draft comments. View those below.
  • Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.

Workflow ID: wflow_LiVZ1hoaBxGC3B33

You can customize Ellipsis by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.

@codesandbox-ci

codesandbox-ci Bot commented Feb 22, 2026 •

Copy link
Copy Markdown

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.

@pkg-pr-new

pkg-pr-new Bot commented Feb 22, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/eslint-plugin-import-x@458

commit: 52d6df9

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Prepares the project for upcoming ESLint 10 compatibility by expanding CI coverage, updating lint-related dependencies (notably @typescript-eslint/* and @babel/eslint-parser), and adjusting a handful of tests to accommodate new parser behaviors/APIs.

Changes:

  • Add ESLint 10 to the CI version matrix and introduce an eslint10 devDependency alias.
  • Bump TypeScript ESLint and Babel ESLint parser dependencies/lockfile to versions compatible with newer ESLint/TypeScript parser behavior.
  • Update/guard tests that rely on removed/changed ESLint APIs and parser restrictions.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
.github/workflows/ci.yml Adds ESLint 10 to the CI matrix.
package.json Updates peer/dev deps for @typescript-eslint/*, adds eslint10 alias.
yarn.lock Lockfile updates reflecting dependency bumps and new ESLint 10 graph.
src/utils/apply-default.ts Adjusts default-options handling to allow undefined.
test/cli.spec.ts Pins “use-at-your-own-risk” import to the eslint9 alias.
test/rules/no-unused-modules.spec.ts Adds ESLint version constraints to rule-tester setup.
test/rules/no-empty-named-blocks.spec.ts Switches specific TS import-type cases to Babel parser.
test/rules/order.spec.ts Switches a specific TS import-type case to Babel parser.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/apply-default.ts Outdated
Comment thread test/rules/no-unused-modules.spec.ts Outdated
Comment thread package.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/apply-default.ts (1)

15-25: ⚠️ Potential issue | 🟠 Major

Preserve user options when defaults are undefined.

With defaultOptions undefined, options becomes [] and the merge loop never applies userOptions, so caller-provided options are dropped. This changes behavior for rules without defaults.

🛠️ Suggested fix
-  const options = defaultOptions
-    ? (structuredClone(defaultOptions) as AsMutable<Default>)
-    : ([] as AsMutable<Default>)
-
-  if (userOptions == null) {
-    return options
-  }
+  if (defaultOptions == null) {
+    return structuredClone((userOptions ?? []) as Default)
+  }
+  const options = structuredClone(defaultOptions) as AsMutable<Default>
+  if (userOptions == null) {
+    return options
+  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/apply-default.ts` around lines 15 - 25, The current logic
initializes options to [] when defaultOptions is undefined, which drops
caller-provided userOptions; update the initialization and return path so
userOptions are preserved: if defaultOptions is undefined and userOptions is
non-null, set options to a mutable structured clone of userOptions (or return
that clone directly) instead of [] so the subsequent merge/return yields the
caller-supplied values; update code referencing defaultOptions, userOptions,
options, structuredClone, and AsMutable<Default> accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/utils/apply-default.ts`:
- Around line 15-25: The current logic initializes options to [] when
defaultOptions is undefined, which drops caller-provided userOptions; update the
initialization and return path so userOptions are preserved: if defaultOptions
is undefined and userOptions is non-null, set options to a mutable structured
clone of userOptions (or return that clone directly) instead of [] so the
subsequent merge/return yields the caller-supplied values; update code
referencing defaultOptions, userOptions, options, structuredClone, and
AsMutable<Default> accordingly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/rules/no-unused-modules.ts (1)

44-45: Stale commented-out @ts-expect-error directive — consider removing the line entirely.

The // // @ts-expect-error`` is effectively dead code now that shouldUseFlatConfig is typed as `any` (from the cast on line 26). Rather than leaving a double-commented directive, it would be cleaner to either remove it or replace it with a plain TODO comment.

Suggested cleanup
-      // // `@ts-expect-error` -- only available in ESLint v9 -- TODO: fix this with ESLint 10 types
+      // TODO: fix this with ESLint 10 types -- shouldUseFlatConfig is only available in ESLint v9
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/rules/no-unused-modules.ts` around lines 44 - 45, Remove the stale
double-commented "@ts-expect-error" directive next to the expression using
shouldUseFlatConfig and ESLINT_USE_FLAT_CONFIG; update the line to be clean
(either delete the commented directive entirely or replace it with a short TODO
comment) because shouldUseFlatConfig is already cast to any on the earlier line
(line with the cast) so the ts-expect-error is no longer needed — locate the
expression referencing shouldUseFlatConfig and ESLINT_USE_FLAT_CONFIG to make
this change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/rules/no-unused-modules.ts`:
- Around line 44-45: Remove the stale double-commented "@ts-expect-error"
directive next to the expression using shouldUseFlatConfig and
ESLINT_USE_FLAT_CONFIG; update the line to be clean (either delete the commented
directive entirely or replace it with a short TODO comment) because
shouldUseFlatConfig is already cast to any on the earlier line (line with the
cast) so the ts-expect-error is no longer needed — locate the expression
referencing shouldUseFlatConfig and ESLINT_USE_FLAT_CONFIG to make this change.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.changeset/hungry-owls-start.md:
- Line 2: The changeset currently labels "eslint-plugin-import-x" as a patch but
also tightens the peer dependency floor for "@typescript-eslint/utils" from
^8.0.0 to ^8.56.0, which is a breaking-of-compatibility within the same major
and should bump the package at least a minor; update the changeset
classification from "patch" to "minor" and expand the changeset description to
mention the tightened "@typescript-eslint/utils" peerDep floor so release notes
accurately reflect the compatibility contraction.

In `@package.json`:
- Line 65: The peer dependency floor for "@typescript-eslint/utils" was
tightened from ^8.0.0 to ^8.56.0 which can break consumers on 8.0.x–8.55.x, so
update the release type in the changeset to reflect this behavioral change: open
the .changeset/hungry-owls-start.md changeset referenced in the PR and change
its version bump from "patch" to "minor" (or alternatively relax the peerDep
back to the previous range if you intend it to be non-breaking); make sure the
changeset summary mentions the peerDep range narrowing and why it's a minor
semver change.
- Line 66: The peerDependencies range for "eslint" currently allows ^10.0.0 but
CI's eslint10 alias targets 10.0.1 only, so either narrow the peerDependencies
to ^10.0.1 or broaden CI to actually test 10.0.0; update package.json by
changing the "eslint" entry in peerDependencies (symbol: "eslint") to ^10.0.1 if
you want to require CI's tested version, or change the eslint10 alias (symbol:
"eslint10") to "npm:eslint@^10.0.0" so CI also exercises 10.0.0.
- Around line 97-98: The package versions are mixed:
`@babel/eslint-parser`@^8.0.0-rc.2 requires `@babel/core`@^8.0.0-rc.2 while the
project pins `@babel/core` and other `@babel/`* packages at ^7.x; resolve this by
either (A) upgrading `@babel/core` and all `@babel/`* packages (e.g., `@babel/core`,
`@babel/preset-env`, `@babel/preset-react`, `@babel/preset-typescript`,
`@babel/plugin-proposal-decorators`) to the compatible ^8.0.0 range, or (B)
downgrade `@babel/eslint-parser` to the latest stable ^7.x release so it matches
the existing `@babel/core`@^7.27.4; pick one approach and make the corresponding
package.json change to keep all `@babel/`* packages on the same major version.

Comment thread .changeset/hungry-owls-start.md
Comment thread package.json
Comment thread package.json
Comment thread package.json Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)

69-73: Heads-up: @babel/eslint-parser@8.0.0-rc.2 is pinned to a release candidate.

The step is correctly gated to matrix.eslint == 10. Since this is a pre-release version, remember to update the pin when a newer RC or stable release of @babel/eslint-parser v8 ships — otherwise the ESLint 10 CI leg may silently fall behind.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/ci.yml around lines 69 - 73, The CI step named "Install
Babel RC Parser for ESLint 10" pins `@babel/eslint-parser`@8.0.0-rc.2 (a release
candidate), which can become stale; update the workflow to remove or revise this
hard pin when a newer RC or the stable v8 is released—locate the step with name
"Install Babel RC Parser for ESLint 10" and replace the fixed
`@babel/eslint-parser`@8.0.0-rc.2 reference with the new stable/RC version (or a
variable like matrix.babel_parser_version) and add a short comment noting to
bump it when v8 stabilizes so the ESLint 10 CI leg stays current.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 63-67: The workflow contains a duplicated job step named "Install
ESLint ${{ matrix.eslint }}" with the same if condition (`${{ matrix.eslint != 9
}}`) and identical run commands (`yarn add -D eslint@${{ matrix.eslint }}
eslint-plugin-unicorn@56` and `yarn --no-immutable`); remove the duplicate step
so the "Install ESLint ${{ matrix.eslint }}" block appears only once to prevent
running yarn add and yarn --no-immutable twice per job.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 69-73: The CI step named "Install Babel RC Parser for ESLint 10"
pins `@babel/eslint-parser`@8.0.0-rc.2 (a release candidate), which can become
stale; update the workflow to remove or revise this hard pin when a newer RC or
the stable v8 is released—locate the step with name "Install Babel RC Parser for
ESLint 10" and replace the fixed `@babel/eslint-parser`@8.0.0-rc.2 reference with
the new stable/RC version (or a variable like matrix.babel_parser_version) and
add a short comment noting to bump it when v8 stabilizes so the ESLint 10 CI leg
stays current.

Comment thread .github/workflows/ci.yml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 15 out of 16 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread test/cli.spec.ts Outdated
Comment thread src/rules/no-unused-modules.ts
Comment thread test/rules/no-unused-modules.spec.ts Outdated
@SukkaW
SukkaW enabled auto-merge (squash) March 11, 2026 16:13
@SukkaW SukkaW closed this Mar 11, 2026
auto-merge was automatically disabled March 11, 2026 16:14

Pull request was closed

@SukkaW
SukkaW deleted the eslint-10-2 branch March 11, 2026 16:14
@SukkaW
SukkaW restored the eslint-10-2 branch March 11, 2026 16:47
@SukkaW SukkaW reopened this Mar 11, 2026
@SukkaW
SukkaW enabled auto-merge (squash) March 11, 2026 16:48
@SukkaW
SukkaW merged commit 60312ee into un-ts:master Mar 11, 2026
52 of 54 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants