ionic-team / stencil

A toolchain for building scalable, enterprise-ready component systems on top of TypeScript and Web Component standards. Stencil components can be distributed natively to React, Angular, Vue, and traditional web developers from a single, framework-agnostic codebase.
https://stenciljs.com
Other
12.51k stars 782 forks source link

feat: Compatibility issue between Ember Glimmer VM and Stencil #4168

Open ArnaudWeyts opened 1 year ago

ArnaudWeyts commented 1 year ago

Prerequisites

Stencil Version

>= 2.22.3

Current Behavior

Stencil components write their properties decorated with f.e. the @Prop decorator to the prototype object of the custom element. However, ember's latest rendering pipeline - Glimmer.js - checks if the property is present on element to differentiate between setting properties or attributes. The outcome is that Glimmer does not set an attribute but instead sets it as a property, resulting in wrong markup.

Here you can see the stencil code that sets the property on the element.

Here you can see the Glimmer.js code that checks the element to determine if it should be a property or an attribute.

Here you can see a reproducable case in codesandbox that displays the difference by rendering using a dynamic property and rendering using a static (string) property in Glimmer.

Screenshot 2023-03-15 at 17 02 45

Because only the internal property is actually set on the custom element, attributes using kebab-case actually behave correctly. Since internally stencil converts those to camelCase and Glimmer's property check doesn't pass.

Expected Behavior

Ideally stencil does not set the property on the custom element at all, and handles this internally. This avoids a whole range of issues that could be introduced by "polluting" the space of the custom-element and also makes the need for the property validation on build-time redundant.

After digging around in the source code I couldn't find a quick solution for this due to my limited experience with the codebase.

Another solution could be to at least prefix the internal properties with something like stencil__ on build time so they don't collide with Glimmer.

System Info

System: node 18.15.0
     Plaform: linux (5.15.63)
   CPU Model: AMD EPYC (2 cpus)
    Compiler: /project/home/arnaudweyts/workspace/node_modules/@stencil/core/compiler/stencil.js
       Build: 1678806593
     Stencil: 2.22.3 🎆
  TypeScript: 4.9.4
      Rollup: 2.42.3
      Parse5: 7.1.2
      Sizzle: 2.42.3
      Terser: 5.16.1

Steps to Reproduce

Reproduced case in codesandbox here.

Code Reproduction URL

https://codesandbox.io/p/sandbox/infallible-platform-y2w7ho?file=%2Fapp%2Finitializers%2Fionic-components.js&selection=%5B%7B%22endColumn%22%3A3%2C%22endLineNumber%22%3A14%2C%22startColumn%22%3A3%2C%22startLineNumber%22%3A14%7D%5D

Additional Information

If this is perceived as a Glimmer.js issue instead of a Stencil issue, I can also open an issue over there.

Thanks a lot for your work on this great framework!

rwaskiewicz commented 1 year ago

Hey @ArnaudWeyts 👋

Thanks for the detailed issue summary! I very much appreciate it 💙

Without a good deal of investigation, it's not clear which project is causing incompatibilities here. The repro steps here will be a big help - I'm going to label this to get further investigated by the team. We have some work scheduled later this year that may help with this, as we have plans to rework how our decorators work under the hood.

Thanks again!