stencil icon indicating copy to clipboard operation
stencil copied to clipboard

bug: top-level await issue

Open runr02 opened this issue 1 year ago • 7 comments

Prerequisites

Stencil Version

2.21.0

Current Behavior

Get build error when using top-level await.

"Module format cjs does not support top-level await."

Expected Behavior

Solution should build successfully.

System Info

System: node 14.17.1

    Compiler: \@stencil\core\compiler\stencil.js
     Stencil: 2.21.0
  TypeScript: 4.9.4
      Rollup: 2.42.3
      Parse5: 7.1.2
      Sizzle: 2.42.3
      Terser: 5.16.1

Steps to Reproduce

in ts file: `export class Hello{ static async SayHello() { return Promise.resolve('Hello World'); } }

export const hello= await Profile.SayHello(); `

in another ts file import variable hello and use. Then build npm run build. You will receive the error.

Code Reproduction URL

Code

Additional Information

No response

runr02 avatar Apr 05 '23 16:04 runr02

Hey @runr02 👋

Thanks for the issue! I don't believe this is an issue with Stencil specifically, as CommonJS (cjs) does not support top-level await. Can you describe your use case a little bit more for us?

rwaskiewicz avatar Apr 05 '23 17:04 rwaskiewicz

We are using dexie (https://dexie.org/) as wrapper for indexed db however this always returns a promise. We want to abstract the dexie call and simply return an object. This way we don't have to await at a higher level of the application (i.e., stencil component).

export const user = await db.users.get(1);

then reference 'user' inside a stencil component.

To add we have set module to esnext and target to es2019. Typescript doesn't complain. We only get an error upon build. Have not set anything that would suggest output format to be cjs.

Here's git hub repo of starter project with replicated issue: https://github.com/runr02/toplevelawaitissue.git

runr02 avatar Apr 05 '23 17:04 runr02

Thanks! I'm going to label this to get it into our backlog for the team to refine.

rwaskiewicz avatar Apr 10 '23 12:04 rwaskiewicz

To add to this, I was until recently building a stencil app which used top level await, and it built fine. So something changed and caused this to regress. What's even weirder is: I didn't change my app/package.json/package-lock.json i just reinstalled the modules with npm i due to the node_modules folder getting wiped and now it doesn't work :( From my git history I can say that it was definitely working April 3, and even reinstalling the node modules with npm ci instead of npm i doesn't help.

cam-narzt avatar Apr 19 '23 19:04 cam-narzt

Here's git hub repo of starter project with replicated issue: https://github.com/runr02/toplevelawaitissue.git

@runr02 I am able to get the component to render after applying this patch:

diff --git a/src/components/my-component/my-component.tsx b/src/components/my-component/my-component.tsx
index eb17b68..acb7f88 100644
--- a/src/components/my-component/my-component.tsx
+++ b/src/components/my-component/my-component.tsx
@@ -1,4 +1,4 @@
-import { Component, Prop } from '@stencil/core';
+import { Component, Prop, h } from '@stencil/core';
 // import { format } from '../../utils/utils';
 import { message } from '../../utils/toplevelawaitissue';

@@ -29,6 +29,6 @@ export class MyComponent {

   render() {
     // return <div>Hello, World! I'm {this.getText()}</div>;
-    return message;
+    return <div>{message}</div>;
   }
 }

Am I missing something here to reproduce this?

HansClaasen avatar Oct 19 '23 22:10 HansClaasen

Here's git hub repo of starter project with replicated issue: https://github.com/runr02/toplevelawaitissue.git

@runr02 I am able to get the component to render after applying this patch:

diff --git a/src/components/my-component/my-component.tsx b/src/components/my-component/my-component.tsx
index eb17b68..acb7f88 100644
--- a/src/components/my-component/my-component.tsx
+++ b/src/components/my-component/my-component.tsx
@@ -1,4 +1,4 @@
-import { Component, Prop } from '@stencil/core';
+import { Component, Prop, h } from '@stencil/core';
 // import { format } from '../../utils/utils';
 import { message } from '../../utils/toplevelawaitissue';

@@ -29,6 +29,6 @@ export class MyComponent {

   render() {
     // return <div>Hello, World! I'm {this.getText()}</div>;
-    return message;
+    return <div>{message}</div>;
   }
 }

Am I missing something here to reproduce this?

@HansClaasen it’s been a while and can take a closer look tomorrow but the issue presented itself when you build “npm run build”

runr02 avatar Oct 19 '23 23:10 runr02

@runr02 you are right. I actually didn't run the build command and only called npm start and it turns out that the behavior in watch mode is different and the error is not thrown there.

After further investigation it turns out that the Stencil compiler always creates CJS artifacts by calling validateDist. There doesn't seem to be any configuration that would prevent that.

I could see two options here:

  1. Add a Stencil configuration option that disables the CJS properties for the dist-lazy and dist-lazy-loader output targets that are added in validateDist
  2. catch the error thrown by generateCjs if it is a toplevel await error but keep throwing other errors

Any advice from the Stencil team would be appreciated. Thanks!

HansClaasen avatar Oct 20 '23 01:10 HansClaasen