Skip to content

build(server): upgrade server workspaces to Node 24#26492

Closed
alexvy86 wants to merge 13 commits intomicrosoft:mainfrom
alexvy86:node24-in-server
Closed

build(server): upgrade server workspaces to Node 24#26492
alexvy86 wants to merge 13 commits intomicrosoft:mainfrom
alexvy86:node24-in-server

Conversation

@alexvy86
Copy link
Copy Markdown
Contributor

@alexvy86 alexvy86 commented Feb 19, 2026

Summary

Node 20 reaches EOL in April 2026. This upgrades the three server workspaces (gitrest, historian, routerlicious) to build on Node 24 (v24.13.1).

  • Add .nvmrc with 24 to each server workspace root
  • Bump @types/node overrides from ^18^24 in all three package.json files; remove the >=22 downgrade rule from routerlicious
  • Regenerate pnpm-lock.yaml in each workspace
  • Fix fs.Stats construction in gitrest-base — constructor is private in Node 24 types, use Object.create(fs.Stats.prototype) instead
  • Add missing readdirCore overload for {encoding:"buffer", withFileTypes:true} in RedisFs — Node 24 adds a Dirent<Buffer>[] overload that the subclass must cover
  • Add skipLibCheck: true to test tsconfig.json files that were missing it — @types/node@24 uses Symbol.dispose/AsyncDisposable which require TypeScript 5.2+, while this repo pins ~5.1.6; skipLibCheck is consistent with what all main tsconfigs already do
  • Dockerfiles not updated yet (secondary to build verification)

Test plan

  • pnpm clean && pnpm install && pnpm build succeeds in server/gitrest on Node 24.13.1
  • pnpm clean && pnpm install && pnpm build succeeds in server/historian on Node 24.13.1
  • pnpm clean && pnpm install && pnpm build succeeds in server/routerlicious on Node 24.13.1

🤖 Generated with Claude Code

alexvy86 and others added 13 commits February 19, 2026 18:08
Node 20 reaches EOL in April 2026. This upgrades gitrest, historian,
and routerlicious to build and run on Node 24 (v24.13.1).

Changes:
- Add .nvmrc (content: 24) to each server workspace root
- Bump @types/node overrides from ^18 to ^24 in all three workspace
  package.json files; remove the >=22 downgrade rule from routerlicious
- Regenerate pnpm-lock.yaml in each workspace
- Fix fs.Stats construction in gitrest-base (constructor is private in
  Node 24 types; use Object.create instead)
- Add missing readdirCore overload for {encoding:"buffer",withFileTypes:true}
  in RedisFs (new Dirent<Buffer>[] overload added to Node 24 types)
- Add skipLibCheck:true to test tsconfig.json files that were missing it;
  @types/node@24 uses Symbol.dispose/AsyncDisposable which require TS 5.2+,
  while this repo uses TS ~5.1.6 — skipLibCheck is consistent with what
  all main tsconfigs already do

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
opossum@8 has an engines constraint of `^22 || ^21 || ^20 || ^18 || ^16`,
which is incompatible with Node 24. v9.0.0 adds Node 24 support
(`^24 || ^22 || ^20`).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add public-hoist-pattern[]=*eslint* to all three server workspace
  .npmrc files so that ESLint plugins are hoisted to the root
  node_modules during Docker builds (pnpm v10 no longer hoists them
  by default without this explicit setting)

- Upgrade zookeeper from ^5.3.2 to ^7.2.0 in services-ordering-
  zookeeper and add workspace-level pnpm overrides in routerlicious
  and historian. zookeeper@5 used nan bindings (nan@2.17-2.19) that
  cannot compile against Node 24's V8 API; zookeeper@7 includes Node
  24 V8 compatibility fixes and pre-built Node 24 binaries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
zookeeper@7.2.0 could resolve nan@2.19.0 which contains V8 API usages
removed in Node 24 (CopyablePersistentTraits, etc.). Force nan@^2.22.0
which includes the Node 24 V8 compatibility fixes in both historian and
routerlicious workspaces so Docker builds succeed on Node 24.

Co-Authored-By: Claude <noreply@anthropic.com>
nan@2.25.0 regressed and fails to compile node-rdkafka and zookeeper
against Node 24's V8 (v8::Undefined() now returns Local<Primitive>
instead of Local<Value> and nan's FunctionCallbackInfo operator[]
template instantiation fails). Pin to 2.22.2 which compiles cleanly.

Co-Authored-By: Claude <noreply@anthropic.com>
node-rdkafka@3.0.1 (pulled in transitively by published server-services
packages) does not set C++20 build flags, causing compilation failures
with Node 24's V8 headers which now require C++20. Override to ^3.4.0
which includes the correct C++ standard flags.

Co-Authored-By: Claude <noreply@anthropic.com>
Regenerate lockfile after changing nan override from '^2.22.0' to '2.22.2'
(exact pin) so frozen lockfile mode in Docker doesn't reject the install.

Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts:
#	server/gitrest/package.json
#	server/gitrest/pnpm-lock.yaml
#	server/historian/pnpm-lock.yaml
#	server/routerlicious/pnpm-lock.yaml
Contrary to the initial assumption, ESLint v8 resolves plugins from the
shareable config file's location in pnpm's .pnpm sibling structure, so
hoisting to the workspace root is not required. Verified by running a
clean Docker build of main (which never had this setting) successfully.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…orkarounds

TypeScript ~5.1.6 didn't understand Symbol.dispose/AsyncDisposable used by
@types/node@24, so we had added skipLibCheck: true as a workaround. Upgrading
to ~5.4.5 (which matches the main repo) properly supports these TS 5.2+ APIs,
making skipLibCheck unnecessary.

Also upgrades @types/lodash to ^4.17.0 to resolve a WeakMap type conflict:
@types/lodash@4.14.x declares WeakMap<K extends object, V> which is
incompatible with TypeScript 5.4's WeakMap<K extends WeakKey, V>.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ESLint v8 resolves plugins from the project directory rather than the
shared config's virtual store directory. Without public-hoist-pattern,
TypeScript 5.4.5's different peer resolution hash for eslint-config-fluid
causes ESLint to fail to find plugins in fresh Docker builds.

Adding public-hoist-pattern[]=*eslint* to all three server workspace
.npmrc files ensures ESLint plugins are hoisted to the workspace root
node_modules/, making them reliably accessible in all environments.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@alexvy86 alexvy86 closed this Apr 14, 2026
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.

1 participant