stencil
stencil copied to clipboard
bug: private state can conflict with global HTML attributes
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Stencil Version
2.10.0
Current Behavior
In the custom elements build, declaring variables on a component with the same name as a global HTML attribute will cause an error upon creating the component programmatically ala someting like document.createElement
: Uncaught DOMException: Failed to construct 'CustomElement': The result must not have attributes
For example, given the following Stencil component:
class MyComponent {
private inputMode = false;
}
Building with the custom elements output target will generate the following:
class MyComponent extends HTMLElement {
constructor() {
super();
this.inputMode = false;
}
}
This violates the HTML standard's requirements for a custom element constructor: (from https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-conformance)
The element's attributes and children must not be inspected, as in the non-upgrade case none will be present, and relying on upgrades makes the element less usable.
The element must not gain any attributes or children, as this violates the expectations of consumers who use the createElement or createElementNS methods.
Expected Behavior
I would expect Stencil to either namespace private variables to prevent this type of unintended collision, or cause a build error when declaring private variables with colliding names. The @Prop()
decorator will already cause a warning if it detects a global attribute name is being used, but private vars and @State()
do not.
Steps to Reproduce
I am seeing this issue in Ionic Frameworks Vue e2e tests, from this private state declaration: https://github.com/ionic-team/ionic-framework/blob/next/core/src/components/picker-internal/picker-internal.tsx#L21
This is because inputMode
is a global attribute: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/inputmode
Code repro steps:
-
git clone https://github.com/willmartian/stencil-ce-repro.git
- In
stencil_lib
runnpm ci && npm run build && npm pack
- In
ce_test_site
runnpm ci && npm run start
Code Reproduction URL
https://github.com/willmartian/stencil-ce-repro
Additional Information
No response
Good catch. Shouldn't the constructor have a super()
call? 🤔
Good catch. Shouldn't the constructor have a
super()
call? 🤔
Yep! Updated the code block.
👋 I took some time to look through the reproduction case, and wasn't able to reproduce this issue. But, I think there may be some wiring-up of things not working here - it doesn't appear that the components in the reproduction case are being auto-defined properly when I run the repro steps:
(I'd expect the error message you mentioned in the console).
I had to tweak your install instructions a bit, as there were checksum mismatches installing the tarball trying to run npm ci
in step 3:
1. git clone https://github.com/willmartian/stencil-ce-repro.git
2. In stencil_lib run npm ci && npm run build && npm pack
- 3. In ce_test_site run npm ci && npm run start
+ 3. In ce_test_site run npm i ../stencil_lib/stencil-test-project-0.0.1.tgz && npm ci && npm start
Is there anything I'm missing there? Any place I should be looking elsewhere for this error message?
Huh, doing the above repro and loading the same network resources, I get the following:

Seeing this in Chrome, FF, and Safari.
Discussed this offline with @willmartian - turns out this isn't reproducible in Firefox v94, but is on FF 95 (and other major browsers)
Any update on this issue , we also see this same issue with some of our components.