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

Component compiles incorrectly for export { ... as default } ESM syntax #4020

Open
nolanlawson opened this issue Feb 27, 2024 · 6 comments
Open
Labels
BUG P3 Up for grabs Issues that are relatively small, self-contained, and ready for implementation

Comments

@nolanlawson
Copy link
Contributor

nolanlawson commented Feb 27, 2024

Description

Consider this component:

class Component extends LightningElement {}
export { Component as default }

Per ES module syntax, it is equivalent to this component:

export default class Component extends LightningElement {}

However, the second one correctly renders, whereas the first does not. (Repro: 08c93cd .) The component appears to not be treated as a LightningElement per the @lwc/compiler – it is simply treated as a plain JavaScript (non-LWC) module.

Steps to Reproduce

08c93cd

Expected Results

export default class Component extends LightningElement {}

is equivalent to

class Component extends LightningElement {}
export { Component as default }

Actual Results

Nothing is rendered, and the component is not registered at runtime as a proper LightningElement.

Version

This issue exists in master today, as well as LWC v5.0.9 (Spring '24) and v3.0.4 (Winter '24). It even repros in LWC v2.11.8 (Summer '22). So this is a longstanding issue.

Possible Solution

Use the export default class ... syntax instead.

Copy link

git2gus bot commented Feb 27, 2024

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

@nolanlawson nolanlawson added the Up for grabs Issues that are relatively small, self-contained, and ready for implementation label Feb 27, 2024
@nolanlawson
Copy link
Contributor Author

nolanlawson commented Feb 27, 2024

I think to solve this, a bare-minimum solution would be:

  1. Detect usage of export { Foo as default }
  2. Check the same JS module to see if there is a class Foo extends LightningElement {}

(The solution would likely be in @lwc/babel-plugin-component.)

I think other, exotic patterns are not strictly necessary to support:

// const Foo
const Foo = class extends LightningElement {}
export { Foo as default }
// Foo imported from elsewhere
import { Foo } from './elsewhere.js'
export { Foo as default }
// really zany
const Foo = (() => { return true && class extends LightningElement {} })()
export { Foo as default }

@nolanlawson nolanlawson changed the title Component does compile correctly when using export { ... as default } ESM syntax Component compiles incorrectly for export { ... as default } ESM syntax Feb 28, 2024
@nolanlawson
Copy link
Contributor Author

We can probably also support some other simple patterns:

class Foo extends LightningElement {}

export default Foo

Maybe even:

const Foo = class extends LightningElement {}

export default Foo

@wjhsf
Copy link
Contributor

wjhsf commented Feb 28, 2024

What are the behavioral differences (in ESM land, outside the LWC context) between export default const Foo = ... vs export { default as Foo }? In particular, when we compile could we just change export { Foo as default } to export default class Foo {} or would that cause side effects?

@nolanlawson
Copy link
Contributor Author

@wjhsf We can't always safely change the ordering, because it matters in certain cases. For example:

export default Foo
class Foo {}

^ This is a syntax error (Cannot access 'Foo' before initialization). (Some minifiers like Terser and SWC will "helpfully" fix it for you though. 🙃)

In particular, when we compile could we just change export { Foo as default } to export default class Foo {} or would that cause side effects?

Maybe, but I wonder if it's better to just leave things alone, since otherwise we could cause other unforeseen problems.

@HermanBide
Copy link

Hi @nolanlawson i would like to contribute and help fix more bugs please let me know where i can be helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BUG P3 Up for grabs Issues that are relatively small, self-contained, and ready for implementation
Projects
None yet
Development

No branches or pull requests

3 participants