-
-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
Extending Builtins (HTMLElement) in @babel/core@7.0.0-beta.40 is not working #7506
Comments
Hey @jvoccia! We really appreciate you taking the time to report an issue. The collaborators If you need any help, or just have general Babel or JavaScript questions, we have a vibrant Slack |
I have encountered the same problem, are inherited built-in prototype methods Input CodeCurrent Behavioran error occurred while running in
|
@kidneyleung - That looks to be a separate problem. Someone on slack pointed out that second option does not setup the prototype of Wrapper correctly, so I think this is the one that is correct. function _wrapNativeSuper(Class) {
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class))
return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return _construct(Class, arguments, _gPO(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writeable: true,
configurable: true
}
});
return _sPO(Wrapper, Class);
} |
@kidneyleung - That issue with Reflect looks to be in _construct - since calling a function with an undefined variable results in an error - would have to do something like typeof Reflect === "object" instead of _typeof(Reflect) - which will fail with that error if Reflect does not exist at all. |
same issue here |
Related to #7020 cc @WebReflection @nicolo-ribaudo @kidneyleung you seems to have another bug, could you please open a new issue? |
Here's a simple reproduction: https://github.com/trusktr/babel/tree/issue-7020 (originally posted at #7020 (comment)) It includes the built output in You can also try |
For anyone needing a quick solution, you can use @Mr0grog's Example: import builtin from 'newless'
class MyEl extends builtin( HTMLElement ) {
connectedCallback() {
console.log('it works!')
}
}
customElements.define('my-el', MyEl)
document.body.appendChild( document.createElement('my-el') ) You can use this to write Custom Elements the ES5-way too: import native from 'newless'
const HTMLElement = native( window.HTMLElement )
function MyEl () {
const self = HTMLElement.call(this)
// ... use `self` here instead of `this`
return self
}
MyEl.prototype = {
__proto__: HTMLElement.prototype,
constructor: MyEl,
connectedCallback() {
console.log(this) // <my-el></my-el>
},
}
customElements.define('my-el', MyEl)
document.body.appendChild( document.createElement('my-el') ) Newless effectively does what plugin-transform-classes should do, and what @WebReflection's babel-plugin-transform-builtin-classes does. Using newless means taking a manual step in your hand-written code, but it isn't much overhead to write. I have my own version of newless over in lowclass with minor changes mostly around making the code more readable. |
@trusktr I get
My custom element: import builtin from 'newless';
class Pop extends builtin(HTMLElement) {
constructor() {
super();
// initialize
this._guts = "42";
this._laughter = this.laughter.bind(this);
}
// intercept changes to _properties_ on an element in JS
get guts() {
return this._guts;
}
set guts(val) {
if (val == this._guts) return;
console.log(val);
this._guts = val;
}
laughter(val) {
this._guts = val;
this.dispatchEvent(new CustomEvent('laugh'));
}
attributeChangedCallback(name, previous, next) {
// intercept changes to _attributes_ on a tag in the HTML
console.log("Attribute changed");
}
connectedCallback() {
// called when the element has been fully inserted into the DOM
console.log("Fully inserted into DOM");
}
disconnectedCallback() {
// called when the element has been fully removed from the DOM
console.log("Removed from DOM");
}
};
customElements.define('pop-menu', Pop); |
updated Babel dependencies _should_ fix Custom Elements when transpiling to ES5: babel/babel#7506
Choose one: is this a bug report or feature request?
Bug Report
Input Code
https://babeljs.io/repl/build/6204/#?babili=false&browsers=&build=&builtIns=false&code_lz=MYGwhgzhAEAqCmEAuB1AlgEwObyQYXCmngA8l4A7DGACVgFkAZAURHgFtKloBvAKD4BfPsACuyAPbtWHLhAB0GeADM0FeAAoAROWQBaAO6YcSLQBo4iVMdwFIEAJQBuPm24HoAXmgYJYzhRI8sAATvBg5DIBSNq6SIY2ps58QA&debug=false&forceAllTransforms=false&shippedProposals=false&circleciRepo=&evaluate=true&fileSize=false&lineWrap=true&presets=es2015%2Cenv&prettier=false&targets=&version=7.0.0-beta.35%2Bpr.7020&envVersion=7.0.0-beta.35%2Bpr.7020
Babel/Babylon Configuration (.babelrc, package.json, cli command)
Expected Behavior
I would expect this Custom Element to be created without an error.
Current Behavior
Instead I see an error in the console saying:
The result of constructing a custom element must be a HTMLElement (Safari)
OR
Failed to construct 'CustomElement': The result must implement HTMLElement interface (Chrome)
Possible Solution
It looks like _wrapNativeSuper has a bug. It was adopted from code in another project, and it appears that code expected that the class it was wrapping had already been converted to ES5 by Babel. Ultimately what looks like is happening is Reflect.construct is never called.
Context
This prevents using Custom Elements in Babel 7.
Your Environment
@babel/core": "^7.0.0-beta.40"
@babel/preset-env": "^7.0.0-beta.40"
The text was updated successfully, but these errors were encountered: