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

top-level-await error using app directory #43382

Closed
1 task done
niicojs opened this issue Nov 25, 2022 · 31 comments · Fixed by #64508
Closed
1 task done

top-level-await error using app directory #43382

niicojs opened this issue Nov 25, 2022 · 31 comments · Fixed by #64508
Assignees
Labels
area: app App directory (appDir: true) kind: bug Confirmed bug that is on the backlog linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@niicojs
Copy link

niicojs commented Nov 25, 2022

Verify canary release

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

Provide environment information

I'm using ky-universal in my project.
next@latest
node LTS (18)

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

pnpm

Describe the Bug

Using pages directory, everything works fine but as soon as I define experimental.appDir = true in next.config.js I have this error:

Module parse failed: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
See https://webpack.js.org/concepts#loaders
Error: The top-level-await experiment is not enabled (set experiments.topLevelAwait: true to enabled it)

Expected Behavior

Just activating experimental pages should not alter anything in pages.

Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster

https://stackblitz.com/edit/nextjs-vwd7jz

To Reproduce

Example available here: https://stackblitz.com/edit/nextjs-vwd7jz
Just remove app dir in next config and it will work again.

NEXT-3126

@niicojs niicojs added the bug Issue was opened via the bug report template. label Nov 25, 2022
@niicojs niicojs changed the title The top-level-await using app directory top-level-await error using app directory Nov 25, 2022
@Fredkiss3
Copy link
Contributor

I think it's a bug with ky-universal, maybe there is a top level await somewhere in the package, as you can see in the error description :

image

@niicojs
Copy link
Author

niicojs commented Nov 25, 2022

There is, but this is totally valid and works fine without the app dir.
The bug is that it works fine without app dir, but not with it (even if ky is only used in pages dir)

@balazsorban44 balazsorban44 added area: app App directory (appDir: true) area: experimental labels Nov 28, 2022
@balazsorban44
Copy link
Member

balazsorban44 commented Nov 28, 2022

This is related to #42741

Here is a workaround:

/** @type {import("next").NextConfig} */
module.exports = {
  experimental: { appDir: true },
  webpack(config) {
    config.experiments = { ...config.experiments, topLevelAwait: true }
    return config
  },
}

@balazsorban44 balazsorban44 added kind: bug Confirmed bug that is on the backlog and removed bug Issue was opened via the bug report template. labels Nov 28, 2022
@shuding shuding self-assigned this Nov 28, 2022
@Renov4ted
Copy link

This is related to #42741

Here is a workaround:

/** @type {import("next").NextConfig} */
module.exports = {
  experimental: { appDir: true },
  webpack(config) {
    config.experiments = { ...config.experiments, topLevelAwait: true }
    return config
  },
}

I don't have that section in my project where to find that

@vadzim
Copy link
Contributor

vadzim commented Mar 1, 2023

for me this workaround works for pages, but not for api.
It's strange) I like top level await)

@Albosonic
Copy link

Albosonic commented Mar 6, 2023

Also building a nextJS 13 app. With apollo, and saw this error. What fixed it for me was moving my my apollo client query into the component. Rather than lexically before it. eg:
this works:

import client from './apollo-client';
import { Inter } from 'next/font/google'
import styles from './page.module.css'

const inter = Inter({ subsets: ['latin'] })

export default async function Home() {
  const { data } = await client.query({
    query: gql`
      query {
        customer {
          id
        }
      }
    `,
  });
  
  return (
    <main className={styles.main}>
      <h1>My Component</h1>
    </main>
  )
}
`
this does not work and I get the top level experiment error:
import { gql } from "@apollo/client";
import client from './apollo-client';
import { Inter } from 'next/font/google'
import styles from './page.module.css'

const inter = Inter({ subsets: ['latin'] })

const { data } = await client.query({
  query: gql`
    query {
      customer {
        id
      }
    }
  `,
});

export default async function Home() {
  
  return (
    <main className={styles.main}>
      <h1>My Component</h1>
    </main>
  )
}
`


worth noting that my config still looks like this:
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
}

module.exports = nextConfig

@sagar285
Copy link

if there is anyone who is able to findout the way to connect next.js 13 to mongodb database pls pin the anaswer over here , this is an big issue now

@vadzim
Copy link
Contributor

vadzim commented Apr 15, 2023

@sagar285 here https://stackoverflow.com/questions/75697312/import-mongoose-lib-in-api-directory-in-next-js-13-2-app-directory-gives-error there's an advise to add erverComponentsExternalPackages: ["mongoose"] option to the next config as a workaround

@azerum
Copy link

azerum commented May 11, 2023

If you don't want to use experimental features in production, you can downgrade to mongoose 6.11.1

By inspecting git blame of bson repo I've found that top-level await was introduced in version 5

mongoose started using bson@5 since version 7, and 6.11.1 is the latest 6.x.y version

@theDanielJLewis
Copy link

I was having this same problem and then downgraded Mongoose to version 6 (and downgraded Typegoose to version 10) and the problem went away!

Thank you! I was pulling out my hair on this one!

And here's my relevant discussion about this in the Mongoose repo: Automattic/mongoose#13419

@Piyusharora2003
Copy link

hii @theDanielJLewis can you tell which version of Mongoose you installed . I too getting same error

@manavm1990
Copy link

This is related to #42741
Here is a workaround:

/** @type {import("next").NextConfig} */
module.exports = {
  experimental: { appDir: true },
  webpack(config) {
    config.experiments = { ...config.experiments, topLevelAwait: true }
    return config
  },
}

I don't have that section in my project where to find that

next.config.cjs

@hrithikvishwakarma001
Copy link

hrithikvishwakarma001 commented Jul 22, 2023

image
image
image

why am I not able to make any requests? Does anyone have any idea about it how to resolve this problem check my screenshot for reference and suggest to me what I should do to make request

@alexbaumgertner
Copy link

From Automattic/mongoose#13252 (comment)

Try to write in next.config.js file:

experimental: {
  appDir: true,
  serverComponentsExternalPackages: ["mongoose"],
},

It helped me.

More: https://nextjs.org/docs/app/api-reference/next-config-js/serverComponentsExternalPackages

@Piyusharora2003
Copy link

@hrithikvishwakarma001 do check the comment by @manavm1990 , it worked for me !

@Lantianyou
Copy link
Contributor

Lantianyou commented Aug 1, 2023

This is not working for me when building a nextjs project. It would be really nice someone take a look. I am using node@18 and next@13.4.12. Even using the previousely mentioned WebPack work around.
image

@jaanli
Copy link

jaanli commented Aug 9, 2023

Also facing this @onefact -- I set experimental: { appDir: true }, in next.config.mjs and set "target": "ES2017", in tsconfig.json.

Added an example here: onefact/new.onefact.org@1519adc

This yields the error:

Failed to compile
./components/visualization/stocks.js
Error: 
  x top level await requires target to es2017 or higher and topLevelAwait:true for ecmascript
   ,-[/Users/me/projects/new.onefact.org/components/visualization/stocks.js:1:1]
 1 | import * as vg from "@uwdata/vgplot";
 2 | 
 3 | await vg.coordinator().exec(
   : ^^^^^
 4 |   vg.loadParquet("aapl", "https://uwdata.github.io/mosaic/data/stocks.parquet", { where: "Symbol = 'AAPL'" })
 5 | );
   `----

Caused by:
    Syntax Error

Any ideas how to debug? Thank you so much!!

@dirtycajunrice
Copy link

This is still an issue as of the latest canary. Just with mongodb pure, you have to disable server minification. Hopefully this is addressed soon.

@luchillo17
Copy link

Uh @jaanli isn't top level await supposed to be an ES2022 feature?

https://caniuse.com/?search=top%20level%20await

@ArianHamdi
Copy link
Contributor

ArianHamdi commented Mar 1, 2024

Same here.
I can't use top-level await in app directory even with enabled topLevelAwait in webpack config.

@luchillo17
Copy link

@ArianHamdi are you using TS? if you do you'll need more than that config in Webpack, you'll need to configure it in the tsconfig.json as well.

@ArianHamdi
Copy link
Contributor

@ArianHamdi are you using TS? if you do you'll need more than that config in Webpack, you'll need to configure it in the tsconfig.json as well.

Hi @luchillo17.
Yes I am using typescript and also set target: ES2017 on the tsconfig.json is there anything else that I need to do?

Can type in the package.json affect this?

@luchillo17
Copy link

Uh @jaanli isn't top level await supposed to be an ES2022 feature?

https://caniuse.com/?search=top%20level%20await

@ArianHamdi Then let me mention it again, top-level await is an ES2022 feature, not an ES2017 one (ES2017 is for ESM, which is a requirement for top-level await), though Idk if that and the experimental Webpack config is enough.

@ArianHamdi
Copy link
Contributor

Uh @jaanli isn't top level await supposed to be an ES2022 feature?
https://caniuse.com/?search=top%20level%20await

@ArianHamdi Then let me mention it again, top-level await is an ES2022 feature, not an ES2017 one (ES2017 is for ESM, which is a requirement for top-level await), though Idk if that and the experimental Webpack config is enough.

Thanks for your quick response.
I tried it using target:ES2022 and with both type:module and type:commonjs also tried webpack topLevelAwait and unfortunately none of this couldn't solve the problem.

Are you able to use top-level await in app directory?

@luchillo17
Copy link

luchillo17 commented Mar 2, 2024

Nope, but my setup is kind of layered, I have an Nx monorepo, with part of the code in a library, and some other in the app, I thought I couldn't because of Nx build executor, but maybe it was Webpack.

Tried again, and made it work, the issue is how you configure Next, this is what I did, and yes it seems ES2017 does work, but I guess it is because Next (or Webpack) automatically changes your tsconfig.json with "module": "esnext" as soon as you do this:

image

To clarify I did not touch the package.json at all, no "type": "module" in mine anywhere.

So the requirements are basically:

  • Enable top-level await in Webpack through the next.config.js|ts as I did in the screenshot.
  • Set "target": "ES2017" or higher in the tsconfig.json.
  • Set "module": "es2022|esnext|system|node16|nodenext" or higher in the tsconfig.json, it depends on the project but Next or Webpack automatically sets it for you on run to esnext, I would lock it to es2022 or node16 instead of next variants.

@parsasabetz
Copy link

I'm trying to get mongoose to work in production without having to use the ES5 syntax and I've tried every possible combination of these configurations you mentioned. I still get a weird Error: TypeError: a.Z.find is not a function when trying to query the database. My configuration looks like this:

module.exports = withNextIntl({
    experimental: {
        esmExternals: "loose",
        serverComponentsExternalPackages: ["mongoose"],
    },
    webpack: (config) => {
        config.experiments ??= {}
        config.experiments.topLevelAwait = true
        console.log(config)
        return config
    },
    logging: {
        fetches: {
            fullUrl: true,
        },
    },
})

And my tsconfig is as:

{
    "compilerOptions": {
        "target": "ES2020",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": true,
        "noEmit": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "bundler",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "incremental": true,
        "plugins": [
            {
                "name": "next"
            }
        ],
        "paths": {
            "@/*": ["./src/*"],
            "@/public": ["./public"]
        }
    },
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
    "exclude": ["node_modules"]
}

Any ideas how to make this work? I do not want to use the ES5 syntax at any cost...

@jaanli
Copy link

jaanli commented Apr 15, 2024

Just FYI, I had to switch from NextJS to Vite (and Vike, for SSR/ISR) because of the lack of support on this issue specifically.

thankfully Claude.ai and GPT-4 make it easy to migrate :)

@luchillo17
Copy link

luchillo17 commented Apr 15, 2024

@jaanli Good for you, you found another solution, even if it means dropping NextJS altogether.

@parsasabetz Try the moduleResolution as Node16, after that I would remove the serverComponentsExternalPackages to test if it has to do with the package not being processed by Webpack, afaik if you set module to esnext you have to do the same for moduleResolution.

@parsasabetz
Copy link

parsasabetz commented Apr 15, 2024

@luchillo17 I still can't figure it out... I've done everything and honestly at this point it seems that it's not just lack of support, it's anti-support lol!
Anyways, is it worth it to go about Prisma now and rewrite the project with Prisma (got not much experience with it by the way...) now? Or should I just accept the fact that Next (or mongoose?) is forcing me to use ES5 for absolutely no clear reason?

@luchillo17
Copy link

After reading your issue again it is more likely to be mongoose's issue instead of NextJS, I don't use it so can't relate to the issue, I usually use MongoDB directly, in fact, I haven't used withNextIntl, and esmExternals is also new to me, I would probably suggest you ask in Mongoose and see if there's a similar type error in their issues.

@timneutkens
Copy link
Member

Since Next.js 13.4.5 webpack has top level await support enabled by default.

Similarly Turbopack supports top level await by default as well.

In writing additional tests in #64508 I found that client components are missing some kind of handling for async modules so I've raised that to @gnoff who is going to have a look on the React side of module loading.

The PR I opened also gets rid of a warning shown by webpack, but it still works fine without that change (i.e. on 14.2)

TLDR:

  • You can remove topLevelAwait: true from the webpack configuration.
  • Turbopack support top level await by default
  • Top level await works with TypeScript if you add target: "ES2017" to the tsconfig.json
  • There's a bug in React that is causing client components using top level await to fail loading. @gnoff is looking into it.

@timneutkens timneutkens added the linear: next Confirmed issue that is tracked by the Next.js team. label Apr 16, 2024
timneutkens added a commit that referenced this issue Apr 17, 2024
## What?

- Changes webpack output target to `es6` (required for `async function`
output)
- Adds tests for top level await in server components and client
components (App Router)
- Converted the async-modules tests to `test/e2e`
- Has one skipped test that @gnoff is going to look into. This shouldn't
block merging this PR 👍


Adds additional tests for top level `await`.

Since [Next.js
13.4.5](https://github.com/vercel/next.js/releases/tag/v13.4.5) webpack
has top level await support enabled by default.

Similarly Turbopack supports top level await by default as well.

TLDR: You can remove `topLevelAwait: true` from the webpack
configuration.


In writing these tests I found that client components are missing some
kind of handling for top level await (async modules) so I've raised that
to @gnoff who is going to have a look.

<!-- Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible we request that
you follow the checklist sections below.
Choose the right checklist for the change(s) that you're making:

## For Contributors

### Improving Documentation

- Run `pnpm prettier-fix` to fix formatting issues before opening the
PR.
- Read the Docs Contribution Guide to ensure your contribution follows
the docs guidelines:
https://nextjs.org/docs/community/contribution-guide

### Adding or Updating Examples

- The "examples guidelines" are followed from our contributing doc
https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md
- Make sure the linting passes by running `pnpm build && pnpm lint`. See
https://github.com/vercel/next.js/blob/canary/contributing/repository/linting.md

### Fixing a bug

- Related issues linked using `fixes #number`
- Tests added. See:
https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md

### Adding a feature

- Implements an existing feature request or RFC. Make sure the feature
request has been accepted for implementation before opening a PR. (A
discussion must be opened, see
https://github.com/vercel/next.js/discussions/new?category=ideas)
- Related issues/discussions are linked using `fixes #number`
- e2e tests added
(https://github.com/vercel/next.js/blob/canary/contributing/core/testing.md#writing-tests-for-nextjs)
- Documentation added
- Telemetry added. In case of a feature if it's used or not.
- Errors have a helpful link attached, see
https://github.com/vercel/next.js/blob/canary/contributing.md


## For Maintainers

- Minimal description (aim for explaining to someone not on the team to
understand the PR)
- When linking to a Slack thread, you might want to share details of the
conclusion
- Link both the Linear (Fixes NEXT-xxx) and the GitHub issues
- Add review comments if necessary to explain to the reviewer the logic
behind a change

### What?

### Why?

### How?

Closes NEXT-
Fixes #

-->


Closes NEXT-3126
Fixes #43382
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: app App directory (appDir: true) kind: bug Confirmed bug that is on the backlog linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.