Skip to content

chore: refresh dev tooling to ESLint 10 and Vitest 4 - #220

Merged
josemarluedke merged 1 commit into
mainfrom
chore/core-dep-refresh
Aug 21, 2026
Merged

chore: refresh dev tooling to ESLint 10 and Vitest 4#220
josemarluedke merged 1 commit into
mainfrom
chore/core-dep-refresh

Conversation

@josemarluedke

Copy link
Copy Markdown
Owner

Workspace-wide dev tooling refresh. The tooling versions were identical across all seven packages, so they move together rather than leaving core ahead of everything else.

package from to
eslint ^9.32.0 ^10.9.0
@eslint/js ^9.32.0 ^10.0.1
eslint-plugin-n ^17.18.0 ^18.3.0
globals ^16.1.0 ^17.11.0
typescript-eslint ^8.38.0 ^8.67.0
prettier ^3.5.3 ^3.9.6
vitest ^3.2.4 ^4.1.11
eslint-plugin-ember ^12.7.0 ^13.5.0
@babel/eslint-parser ^7.x ^8.0.1

ESLint 10 needed four things beyond version numbers

  • eslint-plugin-ember 12 crashes on ESLint 10context.getSourceCode is not a function, since that API was removed. v13 fixes it.
  • @babel/eslint-parser 7 caps its peer at ESLint 9; v8 accepts 10.
  • eslint-plugin-import has no ESLint 10 support at all (peer stops at ^9, and there's no newer release). @docfy/ember used it for exactly one rule — import/extensions — so it moves to the maintained fork eslint-plugin-import-x under the import-x prefix. Its resolver ships a native binary, hence the unrs-resolver entry in allowBuilds.
  • typescript-eslint 8.67 now errors on project alongside projectService rather than ignoring it, so the redundant setting is removed.

One remaining peer warning is unfixable from here: ember-eslint-parser, a transitive dep of eslint-plugin-ember, pins @babel/eslint-parser@^7. Lint works regardless — I verified all seven packages, not just that the warning was cosmetic.

One real code finding

ESLint 10's new preserve-caught-error rule caught something worth fixing in code I wrote earlier: the top-level-await diagnostic in @docfy/ember-cli threw a new Error without attaching the caught one, discarding the original ERR_REQUIRE_ASYNC_MODULE. Now passed as cause.

Vitest 4

Byte-identical snapshots — no serialization change, unlike the jest→vitest move which required regenerating every one. Verified by diffing the .snap files rather than just seeing tests pass.

TypeScript stays at 5.8.3, deliberately

7.0.2 is available and I did not take it. No published typescript-eslint supports it — both latest (8.67.0) and canary cap the peer at >=4.8.4 <6.1.0, so adopting TS 7 would break linting across the workspace. @glint/core 1.5.2 in @docfy/ember is a second constraint. It needs its own pass once the ecosystem catches up, and it's a workspace-wide change anyway given the shared tsconfig.base.json.

Also deliberately not included

A handful of small bumps (@types/hast 3.0.5, @types/unist 3.0.3, @types/debug, debug 4.4.3, yaml 2.9.0) are left for a follow-up. When I applied them I hit a Property 'hProperties' does not exist on type 'LinkData' failure in the two Ember packages, and I could not establish a trustworthy cause — several of my bisection runs were invalidated by stale node_modules, stale lib/ output, and pnpm aborting with ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY while my greps counted partial output as success.

What I did learn looks like a genuine latent fragility worth fixing on its own: neither @docfy/ember-cli nor @docfy/ember-vite declares mdast-util-to-hast, yet both rely on data.hProperties, which only exists because that package augments mdast's Data. Today the augmentation reaches their TypeScript programs transitively, so any change in hoisting can drop it. Declaring the dependency and importing its types explicitly is the durable fix. I'd rather do that as its own change than bundle it here on evidence I don't trust.

@types/node is also left alone pending a decision — see the PR discussion.

Verification

Compile clean across all packages; lint clean in all seven; @docfy/core 59/59, @docfy/ember-vite 60/60, @docfy/plugin-with-prose 2/2; both app builds succeed; routes and templates guards pass; lint:format clean.

🤖 Generated with Claude Code

Workspace-wide tooling update. The tooling versions were identical across all
seven packages, so they move together rather than leaving core ahead.

  eslint                 ^9.32.0  -> ^10.9.0
  @eslint/js             ^9.32.0  -> ^10.0.1
  eslint-plugin-n        ^17.18.0 -> ^18.3.0
  globals                ^16.1.0  -> ^17.11.0
  typescript-eslint      ^8.38.0  -> ^8.67.0
  prettier               ^3.5.3   -> ^3.9.6
  vitest                 ^3.2.4   -> ^4.1.11
  eslint-plugin-ember    ^12.7.0  -> ^13.5.0
  @babel/eslint-parser   ^7.x     -> ^8.0.1

ESLint 10 needed four things beyond version numbers:

- eslint-plugin-ember 12 crashes on ESLint 10 with "context.getSourceCode is
  not a function" — that API was removed. v13 fixes it.
- @babel/eslint-parser 7 caps its peer at ESLint 9; v8 accepts 10.
- eslint-plugin-import has no ESLint 10 support at all. @docfy/ember used it for
  exactly one rule, import/extensions, so it moves to the maintained fork
  eslint-plugin-import-x under the import-x prefix. Its resolver ships a native
  binary, hence the unrs-resolver entry in allowBuilds.
- typescript-eslint 8.67 now errors on `project` alongside `projectService`
  rather than ignoring it, so the redundant setting is removed.

One real code finding, from ESLint 10's new preserve-caught-error rule: the
top-level-await diagnostic in @docfy/ember-cli threw a new Error without
attaching the caught one, discarding the original ERR_REQUIRE_ASYNC_MODULE.
Now passed as `cause`.

Vitest 4 produced byte-identical snapshots — no serialization change, unlike the
jest-to-vitest move which required regenerating them.

TypeScript stays at 5.8.3 deliberately. 7.0.2 is available, but no published
typescript-eslint supports it: both latest (8.67.0) and canary cap the peer at
`<6.1.0`, so adopting TS 7 would break linting everywhere. @glint/core 1.5.2 in
@docfy/ember is a second constraint. It needs its own pass once the ecosystem
catches up.

Verified: compile clean across all packages, lint clean in all seven,
@docfy/core 59/59, @docfy/ember-vite 60/60, @docfy/plugin-with-prose 2/2, both
app builds succeed, routes and templates guards pass, lint:format clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@josemarluedke josemarluedke added the dependencies Pull requests that update a dependency file label Aug 21, 2026
@josemarluedke
josemarluedke merged commit 5ce3ad9 into main Aug 21, 2026
9 checks passed
@josemarluedke
josemarluedke deleted the chore/core-dep-refresh branch August 21, 2026 23:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant