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 for-await not working in bundles #4207

Closed
vtenfys opened this issue Mar 1, 2020 · 18 comments
Closed

Top-level for-await not working in bundles #4207

vtenfys opened this issue Mar 1, 2020 · 18 comments
Labels
bug Something isn't working correctly cli related to cli/ dir upstream Changes in upstream are required to solve these issues

Comments

@vtenfys
Copy link

vtenfys commented Mar 1, 2020

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
@ecyrbe
Copy link
Contributor

ecyrbe commented Mar 1, 2020

Please read the typescript release notes : https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#top-level-await

Top level avait only work for modules

@vtenfys
Copy link
Author

vtenfys commented Mar 1, 2020

@ecyrbe Thanks, however this is a module, and it does work correctly with a regular await. The issue is when using a for await (...) block which isn't detected by Deno in the same way other await statements are.

@nayeemrmn
Copy link
Collaborator

@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 [])
                    ~~~~~

@vtenfys vtenfys changed the title Top-level for-await not working Top-level for-await not working in bundles Mar 1, 2020
@vtenfys
Copy link
Author

vtenfys commented Mar 1, 2020

This may be an upstream bug with TypeScript - adding console.log(data); before line 49 in cli/js/compiler_api_test.ts shows that the execute function is missing async:

$ ./target/debug/deno bundle a.js a.bundle.js                                                                                         
Bundling "file:///Users/david/Code/Rust/deno/a.js"
System.register("a", [], function (exports_1, context_1) {
    "use strict";
    var __moduleName = context_1 && context_1.id;
    return {
        setters: [],
        execute: function () {
            for await (const _ of [])
                ;
        }
    };
});

Emitting bundle to "a.bundle.js"
2.3 kB emitted.

@kitsonk
Copy link
Contributor

kitsonk commented Mar 1, 2020

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.

@kitsonk
Copy link
Contributor

kitsonk commented Mar 15, 2020

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 microsoft/TypeScript#37402.

@kitsonk
Copy link
Contributor

kitsonk commented Mar 31, 2020

There is a PR open and pending review, which has been assigned. Hopefully it will get merged soon, but might not make TS 3.9.

@StarpTech
Copy link

I use Deno 1.0.0 with TS 3.9 and I can still reproduce this issue with the example above.

@kitsonk
Copy link
Contributor

kitsonk commented May 17, 2020

@StarpTech the issue is still open because the upstream bug is not fixed.

@StarpTech
Copy link

@kitsonk yes I saw it afterward. What's missing there? It looks like the PR is stale for 2 months.

@kitsonk
Copy link
Contributor

kitsonk commented May 17, 2020

🤷 I am not able to comment on why PRs are or are not merged in TypeScript.

@ry ry added the bug Something isn't working correctly label May 18, 2020
@ZenLiuCN
Copy link

ZenLiuCN commented May 19, 2020

try this hacking is work: change function=>async function

  execute: async function () {
        s = server_ts_2.serve({ port: 8000 });
        console.log("servce on http://localhost:8000");
        for await (const req of s) {
          req.respond({ body: "hhhhhh" });
        }
      },

@ZenLiuCN
Copy link

// If one of the modules requires support for top-level-await, TypeScript will

is that anybody working on this?

@lucacasonato
Copy link
Member

@ZenLiuCN This is an upstream bug in TypeScript. We can not speed up TypeScript's development.

@bartlomieju bartlomieju added cli related to cli/ dir upstream Changes in upstream are required to solve these issues labels May 19, 2020
@partyka1
Copy link

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

@kt3k
Copy link
Member

kt3k commented Jun 8, 2020

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/

@lukepighetti
Copy link

Apologies if this has been discussed in the past, but Dart doesn't have top level code, instead it uses a main() function as an entry point, which can be marked as async. Would switching to this method be a viable solution?

@nayeemrmn
Copy link
Collaborator

Fixed with swc bundler.

@kitsonk kitsonk closed this as completed Dec 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly cli related to cli/ dir upstream Changes in upstream are required to solve these issues
Projects
None yet
Development

No branches or pull requests