-
Notifications
You must be signed in to change notification settings - Fork 398
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
fix: replace barrel exports from lwc
with @lwc/ssr-runtime
#5034
Conversation
lwc
package with '@lwc/ssr-runtime'lwc
with '@lwc/ssr-runtime'
lwc
with '@lwc/ssr-runtime'lwc
with @lwc/ssr-runtime
unwrap, | ||
createElement, | ||
renderComponent, | ||
} from 'lwc'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some more tests to add:
export * as lwc from 'lwc'
export { doesNotExist } from 'lwc'
export { registerComponent } from 'lwc'
// should be disallowed
We don't have to be perfect about this because there is already ESLint validation on LEX, but we should at least make sure that these cases work correctly.
Also a good way to confirm that the import is actually working is something like
import { LightningElement } from './barrel.js'
// ...
constructor() {
super()
this.isInstanceOfLightningElement = this instanceof LightningElement
}
<template>
{isInstanceOfLightningElement}
</template>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
man the reviews on this team are so fast :D thank you!
export * as lwc from 'lwc'
Thanks, realized exportAllDeclaration is missing and valid, working on it now.
export { doesNotExist } from 'lwc'
Ok got you. I didn't see any coverage like that for imports, I will add some.
export { registerComponent } from 'lwc' // should be disallowed
Is this validation handled in the compiler pass or at runtime? I was confused there perhaps. 4674)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I got mixed up: we don't do any validation of lwc
imports/exports in this repo. It's in eslint-plugin-lwc which runs on-platform already.
I thought we did some validation here, but just checked and couldn't find any.
So I think we only need to test export * as lwc
then. import { doesNotExist }
will likely throw an error at the Rollup level, so not worth testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep looks like it.
} | ||
|
||
path.replaceWith(b.exportAllDeclaration(b.literal('@lwc/ssr-runtime'))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't correctly handle the case of
export * as foo from 'lwc'
which is not the same as
export * from 'lwc'
In this case, we would need to maintain the foo
identifier as well (try this example on https://astexplorer.net/).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you, sorry I missed this
unwrap, | ||
createElement, | ||
renderComponent | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd still love for us to do something with these rather than just logging them. E.g. exposing it on the component so that the template can prove that it rendered something, and that the exports we got from here are the same ones exported from @lwc/ssr-runtime
(i.e. no duplicate modules).
Also, logging here will make our tests more noisy. We already have noisy logs, but this just adds to the problem. We could do something like Promise.resolve(...)
to avoid the compiler removing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd still love for us to do something with these rather than just logging them. E.g. exposing it on the component so that the template can prove that it rendered something
It's a little crude, but what do you think about exposing them in the template via inner-html
? Example here. The function implementations would differ between v1 and v2 ofc so I trimmed them... E.g. getComponentDef
in V1 vs V2 (stub)
Also, logging here will make our tests more noisy. We already have noisy logs, but this just adds to the problem.
Ok makes sense. See above.
.replace('async function serverSideRenderComponent', 'function renderComponent') | ||
) | ||
.join('\n '); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could make this less fragile by using a simple typeof
instead of stringifying the entire function. I also tend to prefer inlining these kinds of things into fixtures instead of having shared utils (code reuse is not super important for fixture tests).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn.name
should also work (unless rollup mangles it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, that works thanks
path.replaceWith( | ||
b.exportNamedDeclaration( | ||
path.node.declaration, | ||
path.node.specifiers, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's structuredClone
these for safety. Ditto below for path.node.exported
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok thank you, I updated Dales replaceLwcImport impl above to keep it consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nits, LGTM
.replace('async function serverSideRenderComponent', 'function renderComponent') | ||
) | ||
.join('\n '); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fn.name
should also work (unless rollup mangles it)
imports = importsToString([ | ||
foo.getComponentDef, | ||
foo.isComponentConstructor, | ||
foo.createContextProvider, | ||
foo.readonly, | ||
foo.setFeatureFlagForTest, | ||
foo.unwrap, | ||
foo.createElement, | ||
foo.renderComponent, | ||
]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imports = importsToString([ | |
foo.getComponentDef, | |
foo.isComponentConstructor, | |
foo.createContextProvider, | |
foo.readonly, | |
foo.setFeatureFlagForTest, | |
foo.unwrap, | |
foo.createElement, | |
foo.renderComponent, | |
]); | |
imports = Object.values(foo).map(fn => fn.name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -23,6 +23,12 @@ import type { CompilationMode } from '@lwc/shared'; | |||
|
|||
const visitors: Visitors = { | |||
$: { scope: true }, | |||
ExportNamedDeclaration(path) { | |||
replaceNamedLwcExport(path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is replaceNamedLwcExport
used anywhere else? Can we just inline it here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not, but same goes for replaceLwcImport so I was just keeping it consistent. Also feel like this file could get a little busy if we added everything inline?
* test(ssr): add tests for nested elements in slots (#5048) * fix(compiler): log warning for missing name/namespace (#4825) * test(karma): remove unnecessary IE11-related code (#5054) * fix: replace barrel exports from `lwc` with `@lwc/ssr-runtime` (#5034) * fix: replace barrel from `lwc` package with '@lwc/ssr-runtime' * fix: handle * barrel case and corresponding tests * fix: function naming * fix: barrel import test parity * fix: include optional exported alias for export all declaration replacement, tests * chore: explain function name massaging in test * fix: deep clone objects and optimize tests * fix: remove unused shared file * test(karma): add test for for:each issue #4889 (#5053) * fix(ssr): missing bookends for slotted lwc:if not at the top-level (#5027) Co-authored-by: Nolan Lawson <[email protected]> * fix(ssr): fix HTML comment bookends for if blocks (#5055) Co-authored-by: Will Harney <[email protected]> * fix(ssr-compiler): namespace and name should be optional in ComponentTransformOptions (#5058) * test(ssr): test `if` with adjacent text (#5056) * test(karma): reduce #4889 even further (#5060) * fix(ssr): fix `style` attribute rendering (#5061) * fix(ssr-compiler): harmonize some wire errors (#5062) Co-authored-by: Will Harney <[email protected]> * fix: only call callback when needed @W-17420330 (#5064) * fix: only call callback when needed @W-17420330 * chore: simplify test * fix: use correct class check * fix(ssr): render from superclass (#5063) Co-authored-by: Nolan Lawson <[email protected]> * test(ssr): add more superclass tests (#5065) * fix: use correct shadow root @W-17441501 (#5070) * fix: use correct shadow root @W-17441501 * chore: yagni i guess * chore: ๐ฉ๏ธ๐ฆ * If you read this, tell me so! * fix(ssr): align csr and ssr reflective behavior (#5050) * chore: release v8.12.2 @W-17485572 (#5075) --------- Co-authored-by: Nolan Lawson <[email protected]> Co-authored-by: jhefferman-sfdc <[email protected]> Co-authored-by: Matheus Cardoso <[email protected]> Co-authored-by: Nolan Lawson <[email protected]> Co-authored-by: Eugene Kashida <[email protected]>
Details
Does this pull request introduce a breaking change?
Does this pull request introduce an observable change?
GUS work item
W-16984771