Skip to content

fix(vite-config): use Node16 module for CJS declaration#352

Merged
lachlancollins merged 5 commits intoTanStack:mainfrom
birkskyum:upgrade-from-cjs-node10-to-node16
Mar 15, 2026
Merged

fix(vite-config): use Node16 module for CJS declaration#352
lachlancollins merged 5 commits intoTanStack:mainfrom
birkskyum:upgrade-from-cjs-node10-to-node16

Conversation

@birkskyum
Copy link
Member

@birkskyum birkskyum commented Mar 14, 2026

Change the CJS dts() pass from module: 1 (Node10) to module: 100 (Node16)

Problem

module: 1 (CommonJS) forces TypeScript to use node10 module resolution when generating CJS declarations (.d.cts). This causes two classes of build failures in downstream monorepos (Router - migrating from /config to the /vite-config package):

  1. TS2742 ("inferred type cannot be named") - node10 resolution doesn't understand package.json exports maps, so it resolves types through physical pnpm store paths (e.g. ../../router-generator/node_modules/@tanstack/virtual-file-routes/dist/cjs/types.cjs) which aren't portable.

  2. TS2307 ("Cannot find module") - Packages that only define an import condition in their exports (no require) are invisible to node10 resolution, causing the CJS declaration pass to fail even though the types exist.

Fix

module: 100 (Node16) is CJS-aware and understands exports maps, so TypeScript resolves types through package names rather than filesystem paths. The beforeWriteFile hook continues to handle .d.ts.d.cts renaming and import extension rewriting as before.

Summary by CodeRabbit

  • Chores
    • Updated CommonJS build output for Node.js 16+ compatibility (moves away from older Node.js semantics).
  • Documentation
    • Added a changeset documenting a patch bump and noting the upgrade path from Node.js 10 to Node.js 16.

@changeset-bot
Copy link

changeset-bot bot commented Mar 14, 2026

🦋 Changeset detected

Latest commit: 5325427

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

This PR includes changesets to release 1 package
Name Type
@tanstack/vite-config 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

@coderabbitai
Copy link

coderabbitai bot commented Mar 14, 2026

Warning

Rate limit exceeded

@lachlancollins has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 5 minutes and 29 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d2a801ed-9087-49c9-8651-a13ffa661178

📥 Commits

Reviewing files that changed from the base of the PR and between 8e985b0 and 5325427.

📒 Files selected for processing (2)
  • .changeset/empty-items-bet.md
  • packages/vite-config/src/index.ts
📝 Walkthrough

Walkthrough

Updates TypeScript compiler setting for the CommonJS dts build to Node16 semantics and adds a changeset file documenting a patch bump and upgrade note from Node10 to Node16.

Changes

Cohort / File(s) Summary
Build config & changeset
.changeset/empty-items-bet.md, packages/vite-config/src/index.ts
Changed TS compiler module for the cjs dts build from CommonJS (1) to Node16 (100). Added a changeset documenting a patch bump and the Node10→Node16 upgrade path.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 I hopped through keys and compiler trees,

Switched CJS to Node16 with ease.
A tiny changeset, a small bright cheer,
Patch bumped paths that once were drear.
Nibbles of TypeScript—forward we steer!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description provides comprehensive context about the problem and solution but is missing the required checklist items from the template. Complete the checklist section by confirming you followed the Contributing guide and tested locally; also confirm whether this requires a changeset (already present) or if it's docs/CI/dev-only.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change: updating the CJS module configuration from Node10 to Node16 in vite-config.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Tip

CodeRabbit can approve the review once all CodeRabbit's comments are resolved.

Enable the reviews.request_changes_workflow setting to automatically approve the review once all CodeRabbit's comments are resolved.

@nx-cloud
Copy link

nx-cloud bot commented Mar 14, 2026

View your CI Pipeline Execution ↗ for commit 5325427

Command Status Duration Result
nx run-many --target=build ✅ Succeeded 7s View ↗
nx affected --targets=test:sherif,test:docs,tes... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-15 14:55:56 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 14, 2026

npm i https://pkg.pr.new/@tanstack/eslint-config@352
npm i https://pkg.pr.new/@tanstack/publish-config@352
npm i https://pkg.pr.new/@tanstack/typedoc-config@352
npm i https://pkg.pr.new/@tanstack/vite-config@352

commit: 5325427

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
.changeset/empty-items-bet.md (1)

5-5: Polish the changeset sentence for clearer release notes.

Consider using canonical capitalization/wording (e.g., CJS, Node10, Node16) to make the changelog easier to scan.

Suggested wording
-fix: upgrade from cjs node10 to node16
+fix: upgrade CJS declaration emit from Node10 to Node16
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.changeset/empty-items-bet.md at line 5, Update the changeset title line
"fix: upgrade from cjs node10 to node16" to use canonical capitalization/wording
for clarity in release notes (e.g., change to "fix: upgrade from CJS / Node 10
to Node 16" or "fix: upgrade from CJS and Node10 to Node16"); edit the existing
changeset sentence (the header string in the diff) to one of these normalized
forms so the changelog is easier to scan.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.changeset/empty-items-bet.md:
- Line 5: Update the changeset title line "fix: upgrade from cjs node10 to
node16" to use canonical capitalization/wording for clarity in release notes
(e.g., change to "fix: upgrade from CJS / Node 10 to Node 16" or "fix: upgrade
from CJS and Node10 to Node16"); edit the existing changeset sentence (the
header string in the diff) to one of these normalized forms so the changelog is
easier to scan.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: de9ca633-d406-4470-817e-2a432c08c194

📥 Commits

Reviewing files that changed from the base of the PR and between fafb869 and b37710f.

📒 Files selected for processing (2)
  • .changeset/empty-items-bet.md
  • packages/vite-config/src/index.ts

@birkskyum birkskyum changed the title Use Node16 module resolution for CJS declaration emit fix: use Node16 module resolution for CJS declaration emit Mar 14, 2026
@lachlancollins lachlancollins changed the title fix: use Node16 module resolution for CJS declaration emit fix(vite-config): use Node16 module for CJS declaration Mar 15, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
packages/vite-config/src/index.ts (2)

59-62: Consider using named constants for TypeScript module kinds.

Both dts() configurations use magic numbers (99, 100) for TypeScript's ModuleKind enum. While the inline comments help, extracting these to named constants would improve maintainability and make future updates clearer.

♻️ Proposed refactor using named constants
+// TypeScript ModuleKind enum values
+const TS_MODULE_ESNEXT = 99
+const TS_MODULE_NODE16 = 100
+
 export const tanstackViteConfig = (options: Options): UserConfig => {

Then update the usages:

         compilerOptions: {
-          module: 99, // ESNext
+          module: TS_MODULE_ESNEXT,
           declarationMap: false,
         },
             compilerOptions: {
-              module: 100, // Node16
+              module: TS_MODULE_NODE16,
               declarationMap: false,
             },

Also applies to: 85-88

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

In `@packages/vite-config/src/index.ts` around lines 59 - 62, The code uses magic
numbers for TypeScript ModuleKind in the dts() configurations
(compilerOptions.module: 99 and 100); create named constants (e.g., const
MODULE_KIND_ESNEXT = /* ModuleKind.ESNext value */ and const MODULE_KIND_ES2020
= /* ModuleKind.ES2020 value */ or use the actual enum import) and replace the
numeric literals in the dts() configuration blocks (references:
compilerOptions.module in the two dts() usages around the current module values)
with those constants to improve readability and maintainability.

86-86: Change correctly enables Node16 module resolution for CJS declaration emit.

Updating module: 1 to module: 100 properly switches to Node16 resolution, which understands exports maps in package.json and resolves TS2742 and TS2307 errors.

Consider using named constants or TypeScript's ModuleKind enum instead of magic numbers (99, 100) for better maintainability and clarity.

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

In `@packages/vite-config/src/index.ts` at line 86, The TS config currently uses
the magic number "module: 100" (in the TS options object where the module field
is set) to enable Node16 module resolution; replace the numeric literal with a
named constant from TypeScript (e.g. ModuleKind.Node16 or ts.ModuleKind.Node16)
by importing ModuleKind/ts and assigning module: ModuleKind.Node16 (and do the
same for any other magic values like 99), and update the inline comment
accordingly so the intent is clear and maintainable.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/vite-config/src/index.ts`:
- Around line 59-62: The code uses magic numbers for TypeScript ModuleKind in
the dts() configurations (compilerOptions.module: 99 and 100); create named
constants (e.g., const MODULE_KIND_ESNEXT = /* ModuleKind.ESNext value */ and
const MODULE_KIND_ES2020 = /* ModuleKind.ES2020 value */ or use the actual enum
import) and replace the numeric literals in the dts() configuration blocks
(references: compilerOptions.module in the two dts() usages around the current
module values) with those constants to improve readability and maintainability.
- Line 86: The TS config currently uses the magic number "module: 100" (in the
TS options object where the module field is set) to enable Node16 module
resolution; replace the numeric literal with a named constant from TypeScript
(e.g. ModuleKind.Node16 or ts.ModuleKind.Node16) by importing ModuleKind/ts and
assigning module: ModuleKind.Node16 (and do the same for any other magic values
like 99), and update the inline comment accordingly so the intent is clear and
maintainable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fab36a6-bc33-4763-a18b-6926811cf352

📥 Commits

Reviewing files that changed from the base of the PR and between b37710f and 8e985b0.

📒 Files selected for processing (1)
  • packages/vite-config/src/index.ts

Copy link
Member

@lachlancollins lachlancollins left a comment

Choose a reason for hiding this comment

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

After a bit of testing, the declaration output between CJS and ESM is actually identical, regardless of what module is set to. The only difference is whether it can resolve other files and therefore successfully compile. It seems safe to change this to NodeNext for both the ESM and CJS declaration output. Unfortunately the duplication is still necessary for dual packaging!

@lachlancollins lachlancollins merged commit 17bcd9b into TanStack:main Mar 15, 2026
6 checks passed
@github-actions github-actions bot mentioned this pull request Mar 15, 2026
@github-actions
Copy link
Contributor

🎉 This PR has been released!

Thank you for your contribution!

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.

2 participants