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

bug: top-level await issue #4231

Open
3 tasks done
runr02 opened this issue Apr 5, 2023 · 7 comments
Open
3 tasks done

bug: top-level await issue #4231

runr02 opened this issue Apr 5, 2023 · 7 comments
Labels
Bug: Validated This PR or Issue is verified to be a bug within Stencil

Comments

@runr02
Copy link

runr02 commented Apr 5, 2023

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

@ionitron-bot ionitron-bot bot added the triage label Apr 5, 2023
@runr02 runr02 changed the title bug: bug: top-level await issue Apr 5, 2023
@rwaskiewicz
Copy link
Contributor

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 rwaskiewicz added the Awaiting Reply This PR or Issue needs a reply from the original reporter. label Apr 5, 2023
@ionitron-bot ionitron-bot bot removed the triage label Apr 5, 2023
@runr02
Copy link
Author

runr02 commented Apr 5, 2023

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

@ionitron-bot ionitron-bot bot removed the Awaiting Reply This PR or Issue needs a reply from the original reporter. label Apr 5, 2023
@rwaskiewicz rwaskiewicz self-assigned this Apr 10, 2023
@rwaskiewicz
Copy link
Contributor

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

@rwaskiewicz rwaskiewicz added the Bug: Validated This PR or Issue is verified to be a bug within Stencil label Apr 10, 2023
@rwaskiewicz rwaskiewicz removed their assignment Apr 10, 2023
@cam-narzt
Copy link
Contributor

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.

christian-bromann added a commit to HansClaasen/stencil that referenced this issue Oct 19, 2023
fixes ionic-team#4231

By default the `vdomRender` build flag is `false`. The Stencil parser detects any usage of a `h` function, this flag will be switched. In the component provided by author of the bug there hasn't been any vDOM to be parsed, therefor there was no usage of the function `h`.

Now, in `callRender` if we end up not having to render any vDOM we used to just attach the string (can also be a boolean or number) as text to the host element. This however doesn't work when a shadow DOM is registered for the component. In this case the text content is added to the light dom which is not being rendered.

To fix this we check if the component has a shadow DOM if attach the text node to that node.
HansClaasen pushed a commit to HansClaasen/stencil that referenced this issue Oct 19, 2023
fixes ionic-team#4231

By default the `vdomRender` build flag is `false`. The Stencil parser detects any usage of a `h` function, this flag will be switched. In the component provided by author of the bug there hasn't been any vDOM to be parsed, therefor there was no usage of the function `h`.

Now, in `callRender` if we end up not having to render any vDOM we used to just attach the string (can also be a boolean or number) as text to the host element. This however doesn't work when a shadow DOM is registered for the component. In this case the text content is added to the light dom which is not being rendered.

To fix this we check if the component has a shadow DOM if attach the text node to that node.
HansClaasen pushed a commit to HansClaasen/stencil that referenced this issue Oct 19, 2023
fixes ionic-team#4231

By default the `vdomRender` build flag is `false`. The Stencil parser detects any usage of a `h` function, this flag will be switched. In the component provided by author of the bug there hasn't been any vDOM to be parsed, therefor there was no usage of the function `h`.

Now, in `callRender` if we end up not having to render any vDOM we used to just attach the string (can also be a boolean or number) as text to the host element. This however doesn't work when a shadow DOM is registered for the component. In this case the text content is added to the light dom which is not being rendered.

To fix this we check if the component has a shadow DOM if attach the text node to that node.
@HansClaasen
Copy link
Contributor

HansClaasen commented Oct 19, 2023

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?

@runr02
Copy link
Author

runr02 commented Oct 19, 2023

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”

@HansClaasen
Copy link
Contributor

@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!

github-merge-queue bot pushed a commit that referenced this issue Nov 17, 2023
* fix(runtime): apply textnodes to shadow DOM instead of light dom

fixes #4231

By default the `vdomRender` build flag is `false`. The Stencil parser detects any usage of a `h` function, this flag will be switched. In the component provided by author of the bug there hasn't been any vDOM to be parsed, therefor there was no usage of the function `h`.

Now, in `callRender` if we end up not having to render any vDOM we used to just attach the string (can also be a boolean or number) as text to the host element. This however doesn't work when a shadow DOM is registered for the component. In this case the text content is added to the light dom which is not being rendered.

To fix this we check if the component has a shadow DOM if attach the text node to that node.

* fix unit test

* use component meta flags to detect shadow dom

---------

Co-authored-by: Hans Claasen <[email protected]>
Co-authored-by: Christian Bromann <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug: Validated This PR or Issue is verified to be a bug within Stencil
Projects
None yet
Development

No branches or pull requests

5 participants