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

[JS compiler] remove registerDecorators for non-LightningElement classes #2701

Closed
nolanlawson opened this issue Feb 22, 2022 · 6 comments · Fixed by #3660
Closed

[JS compiler] remove registerDecorators for non-LightningElement classes #2701

nolanlawson opened this issue Feb 22, 2022 · 6 comments · Fixed by #3660
Labels

Comments

@nolanlawson
Copy link
Contributor

Description

The @lwc/babel-plugin-component generates registerDecorators even for non-LightningElement classes.

Steps to Reproduce

https://webcomponents.dev/edit/MYuFA04EubKHITYFNgQm

Input:

class NotALightningElement {
  foo = 'foo'
}

Output:

class NotALightningElement {
  constructor() {
    this.foo = 'foo';
  }
}

registerDecorators(NotALightningElement, {
  fields: ["foo"]
});

Possible Solution

Potentially we can detect a class without an extends (superclass) and avoid doing registerDecorators on that class.

@uip-robot-zz
Copy link

This issue has been linked to a new work item: W-10736098

@nolanlawson
Copy link
Contributor Author

While we're at it, registerComponent is called for any module that does export default.

@pmdartus
Copy link
Member

While we're at it, registerComponent is called for any module that does export default.

This is by design. There is currently no strong signal in the JavaScript code indicating whether a given default export is an LWC component or not. This is the reason why the LWC compiler uses a conservative approach by wrapping all the export default.

Here are a couple of examples we currently support:

class Foo extends LightningElement {}
export Foo;
import BaseComponent from 'x/baseComponent`; // Note: BaseComponent is effectively a class extending from `LightningElement`.
export default class Foo extends BaseComponent {}

@nolanlawson
Copy link
Contributor Author

I was thinking we could at least skip registerComponent for statically-analyzable obvious cases, like:

export default null

But agreed that we can't know at compile time whether a given export is a LightningElement or not.

Your first example should be export default Foo, right?

@pmdartus
Copy link
Member

Your first example should be export default Foo, right?

No, the first example should also be wrapped with registerComponent.

@nolanlawson nolanlawson changed the title [JS compiler] registerDecorators emitted for non-LightningElement classes [JS compiler] remove registerDecorators for non-LightningElement classes May 6, 2022
@nolanlawson
Copy link
Contributor Author

For a convoluted set of reasons, this bug is blocking downstream lightning-components tests from upgrading LWC.

Basically any JS file with a class gets an LWC import, so if you use Jest to mock that class then you'll bring along an entire mocked copy of the LWC engine, which conflicts with the real one and causes:

Unexpected tag name "lightning-datepicker". This name is a registered custom element, preventing LWC to upgrade the element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants