vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.95k stars 26.87k forks source link

allow importing "server-only" modules in `next.config.js` #65652

Open stefanprobst opened 5 months ago

stefanprobst commented 5 months ago

Link to the code that reproduces this issue

https://github.com/stefanprobst/issue-next-config-server-import

To Reproduce

  1. clone https://github.com/stefanprobst/issue-next-config-server-import and run pnpm install
  2. pnpm run dev
  3. see error message:
 ⨯ Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error

> Build error occurred
Error: This module cannot be imported from a Client Component module. It should only be used from a Server Component.

Current vs. Expected behavior

i am trying to import a module which has import "server-only"; into next.config.js and get the following error:

 ⨯ Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error

> Build error occurred
Error: This module cannot be imported from a Client Component module. It should only be used from a Server Component.

i had assumed that next.config.js would not be read client side.

i also checked whether next.config.js is actually read client-side by adding the following code in next.config.js (and everything still worked, so i guess importing from server-only modules should be ok):

if (typeof document !== "undefined") {
  throw new Error("Reading next.config.js on the client.");
}

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #202403151937 SMP PREEMPT_DYNAMIC Fri Mar 15 19:52:22 UTC 2024
  Available memory (MB): 31401
  Available CPU cores: 16
Binaries:
  Node: 20.12.2
  npm: 10.5.0
  Yarn: 1.22.19
  pnpm: 9.0.6
Relevant Packages:
  next: 14.3.0-canary.57 // Latest available version is detected (14.3.0-canary.57).
  eslint-config-next: N/A
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.4.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Module Resolution

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

also see this discussion: https://github.com/vercel/next.js/discussions/65605#discussioncomment-9393115

KATT commented 4 months ago

I would also want this.

I'm migrating from pages to app directory and my pages depend on publicRuntimeConfig. For my publicRuntimeConfig to work, I'm importing ~/server/env.js which I would very much like to have import 'server-only' in now that the boundary between server and client is more fuzzy

stefanprobst commented 3 months ago

@huozhi could you clarify whether this is indeed an issue, or if this is intended behavior? thank you!

stefanprobst commented 3 months ago

ok so the docs state:

next.config.js is a regular Node.js module ... It gets used by the Next.js server and build phases, and it's not included in the browser build.
Armster15 commented 3 months ago

A slightly hacky workaround I'm using for now:

try {
  require("server-only");
} catch (err) {
  if (err && typeof err === "object" && "code" in err && err.code === "MODULE_NOT_FOUND") {
  } else {
    throw err;
  }
}

But yea, it would be nice if it just worked.

Edit: My workaround only works if server-only is not explicitly included in the package.json.

ScreamZ commented 2 weeks ago

+1 for this feature, I want to mark my server configuration as server only, but I want to check it on build.