-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
fix: compiler handles type-only exports #6199
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| import { createFileRoute } from '@tanstack/react-router' | ||
| import { createServerFn } from '@tanstack/react-start' | ||
| import { loggingMiddleware } from '~/shared-lib' | ||
|
|
||
| /** | ||
| * This route tests that the compiler can handle re-exports through type-only modules. | ||
| * | ||
| * The loggingMiddleware is imported from ~/shared-lib, which re-exports from: | ||
| * - ./middleware (has runtime code) | ||
| * - ./types (has ONLY type exports - compiles to empty JS) | ||
| * | ||
| * If the compiler doesn't handle empty modules correctly, the build will fail with: | ||
| * "could not load module .../types/actions.ts" | ||
| */ | ||
|
|
||
| const getMessage = createServerFn() | ||
| .middleware([loggingMiddleware]) | ||
| .handler(async () => { | ||
| return 'Hello from server with type-only module re-exports!' | ||
| }) | ||
|
|
||
| export const Route = createFileRoute('/type-only-reexport')({ | ||
| component: TypeOnlyReexportPage, | ||
| loader: async () => { | ||
| const message = await getMessage() | ||
| return { message } | ||
| }, | ||
| }) | ||
|
|
||
| function TypeOnlyReexportPage() { | ||
| const { message } = Route.useLoaderData() | ||
| return ( | ||
| <div className="p-2"> | ||
| <h3 data-testid="type-only-heading">Type-Only Re-export Test</h3> | ||
| <p data-testid="message">{message}</p> | ||
| <p> | ||
| This page tests that the compiler can handle barrel files that re-export | ||
| from type-only modules (which compile to empty JavaScript). | ||
| </p> | ||
| </div> | ||
| ) | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,12 @@ | ||||||
| /** | ||||||
| * Library index - re-exports from middleware and types. | ||||||
| * | ||||||
| * This barrel file re-exports from both: | ||||||
| * 1. ./middleware - has runtime code (createMiddleware) | ||||||
| * 2. ./types - has ONLY type exports (compiles to empty JS) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix documentation: path reference inconsistency. The comment refers to 🔎 Proposed fix- * 2. ./types - has ONLY type exports (compiles to empty JS)
+ * 2. ./typedefs - has ONLY type exports (compiles to empty JS)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||
| * | ||||||
| * The compiler must handle the type-only module gracefully when | ||||||
| * tracing exports through this barrel file. | ||||||
| */ | ||||||
| export * from './middleware' | ||||||
| export * from './typedefs' | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| /** | ||
| * Middleware that logs server function calls. | ||
| * This is exported through a barrel file that also re-exports type-only modules. | ||
| */ | ||
| import { createMiddleware } from '@tanstack/react-start' | ||
|
|
||
| export const loggingMiddleware = createMiddleware().server(({ next }) => { | ||
| console.log('[logging] Server function called') | ||
| return next() | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| /** | ||
| * This file contains ONLY type exports. | ||
| * After TypeScript compilation, this becomes an empty JavaScript module. | ||
| * This tests that the compiler can handle re-exports through type-only modules. | ||
| * | ||
| * See: https://github.com/TanStack/router/issues/6198 | ||
| */ | ||
|
|
||
| // biome-ignore lint/suspicious/noExplicitAny: Generic server function type | ||
| export type Action = (...deps: any[]) => any | ||
| export type ActionParams<TFunction extends Action> = Parameters<TFunction>[0] |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| /** | ||
| * Types index - re-exports from type-only modules | ||
| */ | ||
| export * from './actions' |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,39 @@ | ||||||||||||||
| import { expect } from '@playwright/test' | ||||||||||||||
| import { test } from '@tanstack/router-e2e-utils' | ||||||||||||||
|
|
||||||||||||||
| /** | ||||||||||||||
| * These tests verify the compiler can handle type-only module re-exports. | ||||||||||||||
| * | ||||||||||||||
| * The scenario: | ||||||||||||||
| * 1. ~/shared-lib/index.ts re-exports from ./middleware and ./types | ||||||||||||||
| * 2. ~/shared-lib/types/index.ts re-exports from ./actions.ts | ||||||||||||||
| * 3. ~/shared-lib/types/actions.ts contains ONLY type exports (no runtime code) | ||||||||||||||
|
Comment on lines
+8
to
+10
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix documentation: path reference inconsistency. The comments refer to
🔎 Proposed fix * The scenario:
- * 1. ~/shared-lib/index.ts re-exports from ./middleware and ./types
- * 2. ~/shared-lib/types/index.ts re-exports from ./actions.ts
- * 3. ~/shared-lib/types/actions.ts contains ONLY type exports (no runtime code)
+ * 1. ~/shared-lib/index.ts re-exports from ./middleware and ./typedefs
+ * 2. ~/shared-lib/typedefs/index.ts re-exports from ./actions.ts
+ * 3. ~/shared-lib/typedefs/actions.ts contains ONLY type exports (no runtime code)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| * | ||||||||||||||
| * After TypeScript compilation, actions.ts becomes an empty JavaScript module. | ||||||||||||||
| * The compiler must handle this gracefully when tracing exports through | ||||||||||||||
| * barrel files. Without the fix, the build would fail with: | ||||||||||||||
| * "could not load module .../types/actions.ts" | ||||||||||||||
| * | ||||||||||||||
| * If these tests pass, it proves the compiler correctly handles empty modules | ||||||||||||||
| * when following re-export chains. | ||||||||||||||
| */ | ||||||||||||||
|
|
||||||||||||||
| test('page using middleware from barrel with type-only re-exports builds and renders', async ({ | ||||||||||||||
| page, | ||||||||||||||
| }) => { | ||||||||||||||
| // Navigate to the route that uses middleware from ~/shared-lib | ||||||||||||||
| // If the compiler fix isn't working, this page wouldn't exist because | ||||||||||||||
| // the build would have failed | ||||||||||||||
| await page.goto('/type-only-reexport') | ||||||||||||||
| await page.waitForURL('/type-only-reexport') | ||||||||||||||
|
|
||||||||||||||
| // The heading should be visible | ||||||||||||||
| await expect(page.getByTestId('type-only-heading')).toContainText( | ||||||||||||||
| 'Type-Only Re-export Test', | ||||||||||||||
| ) | ||||||||||||||
|
|
||||||||||||||
| // The server function should have executed and returned data | ||||||||||||||
| await expect(page.getByTestId('message')).toContainText( | ||||||||||||||
| 'Hello from server with type-only module re-exports!', | ||||||||||||||
| ) | ||||||||||||||
| }) | ||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix documentation: path reference inconsistency.
The comment refers to
./typesbut the actual directory is./typedefs(as seen in the import on line 3). Update the comment to match the actual directory name.🔎 Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents