[go: nahoru, domu]

Skip to content
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

Page.tsx with default and named export fails on build (esLint) #53940

Open
1 task done
oliverkidd opened this issue Aug 12, 2023 · 12 comments
Open
1 task done

Page.tsx with default and named export fails on build (esLint) #53940

oliverkidd opened this issue Aug 12, 2023 · 12 comments
Labels
bug Issue was opened via the bug report template. TypeScript Related to types with Next.js.

Comments

@oliverkidd
Copy link

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.1.0: Sun Oct  9 20:15:09 PDT 2022; root:xnu-8792.41.9~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.14.0
      npm: 9.3.1
      Yarn: N/A
      pnpm: N/A
    Relevant Packages:
      next: 13.4.14-canary.2
      eslint-config-next: 13.4.13
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router, ESLint (eslint-config-next), TypeScript (plugin, built-in types)

Link to the code that reproduces this issue or a replay of the bug

N/a

To Reproduce

Create a page.tsx file in the app dir with a default export for the page, and a named export to represent any util function.

export default function Page() {
return (
// page return
)
}

export function utilHelper(){
return (
// function return
)
}

Describe the Bug

Previously I have been able to have named exports in addition to a default export in my page.tsx files.
All of a sudden the above configuration of a page.tsx file now fails on build with the error:

"Type error: Page "pathtopage/page.tsx" does not match the required types of a Next.js Page.
"utilHelper" is not a valid Page export field."

As far as the current build of the site running on vercel suggests, and as the docs state, one should be able to export in this way from any file, including page.tsx.

Expected Behavior

no erros when exporting a named function with a default export from a file

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

vercel

@oliverkidd oliverkidd added the bug Issue was opened via the bug report template. label Aug 12, 2023
@github-actions github-actions bot added the TypeScript Related to types with Next.js. label Aug 12, 2023
@jlous
Copy link
jlous commented Nov 14, 2023

This is pretty major - makes it impossible to test such functions without moving them out of their context

@sawyerh
Copy link
sawyerh commented Dec 15, 2023

Would love to see an option to disable or configure this TypeScript plugin feature. My use case: In order to make it easier to render the interface portion of async server components in tests and Storybook, I would like to follow a pattern like below, but this is prevented by this named export issue:

export default async function Controller() {
  const claim = await getExampleData()
  return <View claim={claim} />
}

export function View(props) {
  return <div>{props.claim.id}</div>
}
Type error: Page "src/app/example/page.tsx" does not match the required types of a Next.js Page.
  "View" is not a valid Page export field.

Example test that this pattern would support:

import { View } from "src/app/example/page"

it("passes accessibility scan", () => {
    const { container } = render(<View claim={{ id: "123" }} />)
    const a11y = await axe(container)
    expect(a11y).toHaveNoViolations()
})

Example Storybook story:

import { View } from "src/app/example/page"

const story = {
  component: View,
 args: {
   claim: { id: "123" }
 }
}

Related #56832, #50870

sawyerh added a commit to navapbc/template-application-nextjs that referenced this issue Dec 20, 2023
## Ticket

Resolves #66

## Changes

This is purely an architecture migration and nothing functionally should
have changed.

**Pages Router → App Router**:

- `pages/_app.tsx` → `app/[locale]/layout.tsx`
- `pages/index.tsx` → `app/[locale]/page.tsx` 
- `pages/health.tsx` → `app/[locale]/health/page.tsx` 
- `pages/api/hello.ts` → `app/api/hello/route.tsx` 

**Internationalized routing and locale detection**:

App Router doesn't include built-in support for internationalized
routing and locale detection like Pages Router.

- Added Next.js Middleware (`src/middleware.ts`) to detect and store the
user's preferred language, and routing them to `/es-US/*` when their
preferred language is Spanish
- Added `i18n/server.ts` to contain server-side configuration for the
`next-intl` plugin. This makes locale strings available to all server
components

## Context for reviewers

- [See the related
ADR](https://github.com/navapbc/template-application-nextjs/blob/main/docs/decisions/app/0008-app-router.md)
for why we're moving towards App Router.
- A page file is restricted in what it can export, hence why `view.tsx`
exists instead of that component being colocated in the `page.tsx` file.
[More context on this Next.js
issue](vercel/next.js#53940 (comment)).
@meymeynard
Copy link

Hello. Also experiencing this. Is there any update? Thanks

@absolutegravitas
Copy link

Also affected... could you guys have made a more inscrutable error... seriously...

@guidocaru

This comment has been minimized.

@DavidCodesDev
Copy link

I'm so close to losing my sh*t with Nextjs

@Lsnsh
Copy link
Contributor
Lsnsh commented May 7, 2024
export default function Page() {
  // ...
}

Splitting the non default export from the page file, it works normally.

As for why, it doesn’t seem to be mentioned in the docs.

https://nextjs.org/docs/app/building-your-application/routing/pages

@0xFlo
Copy link
0xFlo commented May 7, 2024

Based on the issues you're encountering with Next.js during your build process, it seems you're running into a common problem with Next.js's stricter validation of page exports in version 14. This validation aims to ensure that page files only export React components that are intended to be used as pages, not utility functions or other named exports. You need to tackle this with a precise refactor to align with best practices and address the compilation errors effectively

Understanding the Issue
Next.js expects that files under the pages directory (or any file treated as a page component) should only default export a React component that corresponds to a page. If you have other named exports, it can cause the build to fail as Next.js might interpret them as potential page candidates which they are not.

Solution: Restructure Exports and Component Organization
To resolve this issue, we need to separate utility functions or non-page components from the page files, ensuring that only the default page export is present in page component files. Here’s how you can adjust your setup:

Separate Utility Functions and Shared Components:
Move any named exports that are not page components into separate files within a suitable directory, such as components or utils.
Adjust Imports in the Main Page File:
Update import statements in your main page files to reflect these changes.

@0xFlo
Copy link
0xFlo commented May 7, 2024

see also: #56825

@confusingbits
Copy link
confusingbits commented Jun 12, 2024

align with best practices

If this is really the reason, and not a technical requirement, I would strongly encourage that this requirement is removed.

It is not 'best practices' that is literally just an opinion. An equally valid opinion is to prefer locality of behavior, which this rule impairs. React itself pushed back against 'best practices' when it was built, and now think of components as concerns, not technologies. Locality of behavior underlies this concept.

You may disagree, but it's all opinions.

If this export restriction is not a technical requirement, I would prefer to see this error removed.

@kika
Copy link
kika commented Jun 22, 2024

I'm observing this in an unexpected setting: the project has src/app/page.tsx export a default React component and a utility function. Project builds normally. As soon as I add 'use client' to one of the components imported by the page I'm seeing this error.
14.2.4

@naingarkar
Copy link

I was also experiencing this kind of error showing

Type error: Page "app/page.tsx" does not match the required types of a Next.js Page.
  "CommentsPage" is not a valid Page export field.

Then I found out it was due to exporting another function inside page.tsx like that

'use client'
export function CommentsPage() => {
}

export default function Page() => {
     <CommentsPage/>
}

So, I tried to move that CommentsPage into another file like you did and build then everything fine.
And I also found another way of doing it in page.tsx like that by removing export keyword from it.

'use client'
function CommentsPage() => {
}

export default function Page() => {
     <CommentsPage/>
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. TypeScript Related to types with Next.js.
Projects
None yet
Development

No branches or pull requests