deno: Top-level for-await not working in bundles

Steps to reproduce

Create server.js with the following content:

import { serve } from "https://deno.land/std@v0.35.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}

Run deno bundle server.js out.js

Run deno out.js

Expected result

The code runs

Actual result

error: Uncaught SyntaxError: Unexpected reserved word
► file:///path/to/out.js:113:17

113             for await (const req of s) {
                    ~~~~~

Notes

Adding await console.log("test"); or any other await statement is detected by the bundler and allows the for-await block to work properly. (See #4206)

deno 0.35.0
v8 8.1.310
typescript 3.8.2

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 4
  • Comments: 18 (8 by maintainers)

Most upvoted comments

would be good to change server example in the docs, because right now first code you run and do deno bundle yields you an error, code taken literally from section First steps

I was wrong, it is part of the Stage 3 proposal. I just got confused because it was implemented in V8 separately. The TypeScript implementation is incomplete and I have opened https://github.com/microsoft/TypeScript/issues/37402.

@davidbailey00 Can you append “in bundles” to the title?

Better repro: a.js:

for await (const _ of []);
export {};

deno bundle a.js a.bundle.js && deno a.bundle.js:

Bundling "file:///mnt/c/Users/Nayeem/projects/deno/a.js"
Emitting bundle to "a.bundle.js"
2.3 kB emitted.
error: Uncaught SyntaxError: Unexpected reserved word
► file:///mnt/c/Users/Nayeem/projects/deno/a.bundle.js:107:17

107             for await (const _ of [])
                    ~~~~~

Surrounding the for-await block with main function seems working around the problem.

import { serve } from "https://deno.land/std@0.55.0/http/server.ts";
const s = serve({ port: 8000 });
console.log("http://localhost:8000/");
async function main() {
  for await (const req of s) {
    req.respond({ body: "Hello World\n" });
  }
}
main()
$ deno bundle example.ts > bundle.js
Bundling file:///Users/kt3k/3/deno/ex.ts
$ deno run -A bundle.js 
http://localhost:8000/

Top level for ... await is seperate in the standards process from Top level await. TypeScript has not implemented it, because it isn’t progressed far enough in the standards. We are actually ignoring an error in the compiler that complains about it, because we can support it. So it is an upstream bug/limitation.

A work around for now would be to use a top level await in the module somewhere else, that would trigger TypeScript to emit the execute as an async function and everything else should work.