vercel / next.js

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

Import with top level await stucks dev server with `--turbo` #65278

Open pawelblaszczyk5 opened 2 weeks ago

pawelblaszczyk5 commented 2 weeks ago

Link to the code that reproduces this issue

https://github.com/pawelblaszczyk5/async-module-turbo-repro

To Reproduce

  1. Start the development server
  2. Try to open localhost:3000 in the browser
  3. Observe it never actually loading (if it loads, try to remove the import with top level await from page.tsx and add it back after sucessful compilation)

Video with reproduction:

https://www.youtube.com/watch?v=PJ9jI-0uDmg

As you can see it sometimes work after restarting the dev server or removing and adding back the import. In console I'm not getting GET / 200 in xxms sometimes and my browser is stuck loading, top bar spinning.

Current vs. Expected behavior

It should work fine, the same way as it does without --turbo.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:10:42 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6000
  Available memory (MB): 16384
  Available CPU cores: 8
Binaries:
  Node: 20.10.0
  npm: 10.2.3
  Yarn: 1.22.19
  pnpm: 8.15.7
Relevant Packages:
  next: 14.3.0-canary.36 // Latest available version is detected (14.3.0-canary.36).
  eslint-config-next: N/A
  react: 18.3.1
  react-dom: 18.3.1
  typescript: 5.1.3
Next.js Config:
  output: N/A

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

Turbopack

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

next dev (local)

Additional context

No response

PACK-3039

timneutkens commented 1 week ago

Seems the minimal reproduction is this:

// app/page.tsx
import { x } from "./test";

/** Add your relevant code here for the issue to reproduce */
export default function Home() {
  return <h1>Hello world abc {x}</h1>;
}
// app/test.ts
export const x = 5;

const a = 10;
if (a !== 10) {
  await new Promise((resolve) => setTimeout(resolve, 100));
}

Anytime the condition is false it will get stuck, if the condition is true is does not get stuck. I.e. if (a === 10) { does not get stuck.

Sandbox: https://codesandbox.io/p/github/pawelblaszczyk5/async-module-turbo-repro/csb-28s59w/draft/clever-christian?file=%2Fapp%2Ftest.ts%3A1%2C1-7%2C1