oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
72.99k stars 2.66k forks source link

Top level await in Bun.build: error: "await" can only be used inside an "async" function #12508

Open huseeiin opened 1 month ago

huseeiin commented 1 month ago

What version of Bun is running?

1.1.18+5a0b93523

What platform is your computer?

Linux 6.5.0-18-generic x86_64 x86_64

What steps can reproduce the bug?

  1. Clone https://github.com/huseeiin/bun-bug
  2. Run bun run build and bun preview
  3. Now, to make it work:
  4. Go to adapter/index.js
  5. Uncomment everything under "if you use rollup, its going to work"
  6. Comment Bun.build bit under "if you use bun, it will not work"

What is the expected behavior?

For the output to match rollup's

What do you see instead?

Its using await in a non-async function unlike rollup

Additional information

No response

huseeiin commented 1 month ago

it also works with esbuild:

await esbuild.build({ bundle: true, format: 'esm', external: ['bun:sqlite'], entryPoints: [`${tmp}/index.js`, `${tmp}/manifest.js`], platform: 'node', outdir: `${out}/server` })
190n commented 1 month ago

Here's a smaller reproduction:

// root.ts
const { getValue } = await import('./module');
// with static instead of dynamic import it works
// import { getValue } from './module';
console.log(getValue());
// module.ts
async function computeValue() {
    return 5;
}

const value = await computeValue();

export function getValue() {
    return value;
}
$ bun run root.ts
5
$ bun build root.ts | bun run -
26 |   value = await computeValue();
                     ^
error: "await" can only be used inside an "async" function
    at /Users/ben/code/repro/[stdin]:26:17

26 |   value = await computeValue();
                                   ^
error: Expected "=>" but found ";"
    at /Users/ben/code/repro/[stdin]:26:31

Bun v1.1.20 (macOS arm64)

The problematic part of the output is:

var init_module = __esm(() => {
  value = await computeValue();
});
huseeiin commented 1 month ago

Here's a smaller reproduction:

// root.ts
const { getValue } = await import('./module');
// with static instead of dynamic import it works
// import { getValue } from './module';
console.log(getValue());
// module.ts
async function computeValue() {
  return 5;
}

const value = await computeValue();

export function getValue() {
  return value;
}
$ bun run root.ts
5
$ bun build root.ts | bun run -
26 |   value = await computeValue();
                     ^
error: "await" can only be used inside an "async" function
    at /Users/ben/code/repro/[stdin]:26:17

26 |   value = await computeValue();
                                   ^
error: Expected "=>" but found ";"
    at /Users/ben/code/repro/[stdin]:26:31

Bun v1.1.20 (macOS arm64)

The problematic part of the output is:

var init_module = __esm(() => {
  value = await computeValue();
});

thanks, this is really good, i admit my original reproduction is a little huge.

paperdave commented 1 month ago

image we are missing the equivalent of this line in esbuild

it comes from the validateTLA function which we dont have. i think the best path for this is to implement the entire logic (which is a bit just to get to one boolean), so that we can un-todo the following test cases (this function is what produces the errors for them)