-
Notifications
You must be signed in to change notification settings - Fork 401
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
chore(ssr): use subpath imports for estree validators #5102
Conversation
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 added a __stack
feature for the validators which might be useful, but it might be better to make a follow up PR for it. It works but I didn't give it much thought.
Error: Validation failed for templated node. Expected type identifier, but received Literal.
at /lwc/packages/@lwc/ssr-compiler/src/compile-template/transformers/text.ts:24:69
❯ ../ssr-compiler/src/compile-template/transformers/text.ts:24:69
22| const bBufferTextContent = esTemplateWithYield`
23| didBufferTextContent = true;
24| textContentBuffer += massageTextContent(${/* string value */ is.identifier});
| ^
25| `<EsExpressionStatement[]>;
26|
❯ ../ssr-compiler/src/compile-template/ir-to-es.ts:11:32
(validateReplacement as any).__debugName || | ||
validateReplacement.name || | ||
'(could not determine)'; | ||
validateReplacement.__debugName || validateReplacement.name || '(could not determine)'; | ||
const actualType = Array.isArray(replacementNode) | ||
? `[${replacementNode.map((n) => n && n.type).join(', ')}]` | ||
: replacementNode?.type; | ||
throw new Error( | ||
const error = new Error( | ||
`Validation failed for templated node. Expected type ${expectedType}, but received ${actualType}.` | ||
); | ||
|
||
if (validateReplacement?.__stack) { | ||
error.message += `\n${validateReplacement.__stack.split('\n')[1]}`; | ||
error.stack = validateReplacement.__stack; | ||
} | ||
|
||
throw error; |
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.
With the type information, there's no need for as any
.
val.__debugName = key; | ||
Object.defineProperty(is, key, { | ||
get: function get() { | ||
const stack: { stack?: string } = {}; | ||
Error.captureStackTrace(stack, get); | ||
val.__stack = stack.stack; | ||
return val; | ||
}, | ||
}); |
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 feature, if deemed useful, can be added in a separate PR.
export function parseHTML(ctx: ParserCtx, source: string) { | ||
export function parseHTML( | ||
ctx: ParserCtx, | ||
source: string | ||
): parse5.DefaultTreeAdapterTypes.DocumentFragment { |
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 fixes an error/warning caught after the tsconfig changes:
The inferred type of 'parseHTML' cannot be named without a reference to '../../../../../node_modules/parse5/dist/tree-adapters/default'. This is likely not portable. A type annotation is necessary.ts(2742)
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.
__debugName
was meant to be a temporary hack because we were doing a lot of changes to the templates and the errors weren't great for debugging. This feels like making it a permanent hack, but I'm not convinced that's something we want to do.
@wjhsf do you have a better idea for |
Co-authored-by: Will Harney <[email protected]>
for (const [key, val] of entries(is)) { | ||
(val as any).__debugName = key; | ||
val.__debugName = key; |
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.
val
here is still the function from estree-toolkit
, so is.identifier
imported via the actual package will still be modified. 😓
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.
True. I guess the only immediate win is making this compatible with esm, which admittedly isn't much for a debug-only feature.
@@ -47,6 +47,9 @@ | |||
} | |||
} | |||
}, | |||
"imports": { | |||
"#estree/*": "./src/estree/*.js" | |||
}, |
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 would avoid package imports
/exports
. We've had issues in the past with Rollup/Jest and how it consumes exports
.
Thanks for the PR! Overall this feels like a lot of added code and complexity for what is essentially just nicer dev error messages... A couple questions:
|
@nolanlawson @wjhsf thanks for the feedback! Let me rethink this one. I'll see if something can be done in Also how often is this debug info being useful for you? Isn't typescript catching everything? Considering that, would the |
Not very often, we went with the quick ugly hack because we were planning on removing it once ssr-compiler is stable.
Not quite, because we have to manually introduce types when we use
It's neat! But we usually already have a pretty good idea of which thing is causing an error, because we're usually only screwing up one |
Details
Currently, the
is
import fromestree-toolkit
is conditionally modified to add some debug information:lwc/packages/@lwc/ssr-compiler/src/estree/validators.ts
Lines 29 to 34 in b2468c9
However this only works for cjs (require), not esm (import), which is explains the setup code in this test:
lwc/packages/@lwc/ssr-compiler/src/__tests__/estemplate.spec.ts
Lines 13 to 16 in b2468c9
This PR aims to replace this approach by exporting a new
is
object fromestree/validators.ts
instead, including types for the debug info.All other files previously importing
is
fromestree-toolkit
are modified to importis
fromestree/validators.ts
.To make this easier a subpath import was added:
#estree/*
so the import can easily be changed fromestree-toolkit
to#estree/validators
.This required changing a few compiler options in
tsconfig.json
(previously discussed here: #4484 (comment)).TODO
tsconfig.json
and subpath imports won't cause breaking changesDoes this pull request introduce a breaking change?
Does this pull request introduce an observable change?
GUS work item