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

refactor(ssr): add back references to esTemplate and infer types #4660

Merged
merged 30 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
add2850
refactor: list all IR nodes explicitly
wjhsf Oct 3, 2024
6d243e7
feat(ssr): implement iterator:* directive
wjhsf Oct 7, 2024
eb437e7
test(ssr): add test for multiple iterator blocks
wjhsf Oct 7, 2024
918d63d
fix(ssr-for-of): use empty array as default for missing iterator
wjhsf Oct 7, 2024
33081fa
fix(ssr): update error in for-of directive for invalid value
wjhsf Oct 7, 2024
abbdd81
Merge branch 'master' into wjh/ssr-for-of
wjhsf Oct 8, 2024
1d9279b
Merge branch 'master' into wjh/ssr-for-of
wjhsf Oct 9, 2024
9a6c751
chore(eslint): don't enforce header in spec files
wjhsf Oct 9, 2024
b206c51
test(lwc-if): add tests for lwc:if, lwc:elseif, and lwc:else
wjhsf Oct 9, 2024
bad14d7
feat(ssr): handle lwc:elseif
wjhsf Oct 9, 2024
2859869
fix(ssr): add comments to lwc:if output
wjhsf Oct 9, 2024
a2578f2
fix(ssr): don't add comments for if:true and if:false
wjhsf Oct 9, 2024
17485d7
Merge branch 'master' into wjh/ssr-lwc-component
wjhsf Oct 9, 2024
55c6306
feat(ssr): explicitly disallow lwc:dynamic
wjhsf Oct 9, 2024
798cce0
fix(ssr): only complain about lwc:dynamic if it gets used
wjhsf Oct 10, 2024
fc08068
Merge branch 'wjh/ssr-lwc-if' into wjh/ssr-lwc-component
wjhsf Oct 10, 2024
07fae75
Merge branch 'master' into wjh/ssr-lwc-component
wjhsf Oct 16, 2024
c0e3cfb
refactor(ssr): update `esTemplate` for better type inferencing
wjhsf Oct 16, 2024
32af940
refactor(ssr): update `esTemplate` usage
wjhsf Oct 16, 2024
d2d3d79
refactor(ssr): re-use replacement node validation
wjhsf Oct 16, 2024
0d66d92
refactor(ssr): update esTemplates to use back refs
wjhsf Oct 16, 2024
9a962b1
fix(ssr): ensure `esTemplate` type inferences work properly
wjhsf Oct 16, 2024
c7bc20d
fix(ssr): add predicate return type
wjhsf Oct 16, 2024
40b6b21
Merge branch 'master' into wjh/ssr-edge
wjhsf Oct 18, 2024
6c0f901
Merge branch 'master' into wjh/ssr-edge
wjhsf Oct 21, 2024
87997a2
Update packages/@lwc/ssr-compiler/src/estemplate.ts
wjhsf Oct 21, 2024
451f6ca
chore(ssr): clean up `isBool`
wjhsf Oct 21, 2024
3332087
chore(ssr): clean up types
wjhsf Oct 21, 2024
fb33df4
chore(ssr): clean up `ToReplacementParameters`
wjhsf Oct 21, 2024
27eab2a
chore(ssr): avoid unnecessary conditional
wjhsf Oct 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ssrFiles": {
"error": "error-ssr.txt",
"expected": "expected-ssr.html"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
SSR compilation error:
The lwc:dynamic directive is not supported for SSR. Use <lwc:component> instead.
26 changes: 16 additions & 10 deletions packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,9 @@ async function compileFixture({ input, dirname }: { input: string; dirname: stri
lwcRollupPlugin({
targetSSR: true,
enableDynamicComponents: true,
modules: [
{
dir: modulesDir,
},
],
// TODO [#3331]: remove usage of lwc:dynamic in 246
wjhsf marked this conversation as resolved.
Show resolved Hide resolved
experimentalDynamicDirective: true,
modules: [{ dir: modulesDir }],
}),
],
onwarn(warning) {
Expand All @@ -64,14 +62,22 @@ function testFixtures() {
pattern: '**/index.js',
},
async ({ filename, dirname, config }) => {
const compiledFixturePath = await compileFixture({
input: filename,
dirname,
});

const errorFile = config?.ssrFiles?.error ?? 'error.txt';
const expectedFile = config?.ssrFiles?.expected ?? 'expected.html';

let compiledFixturePath;
try {
compiledFixturePath = await compileFixture({
input: filename,
dirname,
});
} catch (err: any) {
return {
[errorFile]: `SSR compilation error:\n${err.message}`,
[expectedFile]: '',
};
}

const module = (await import(compiledFixturePath)) as FixtureModule;

let result;
Expand Down
36 changes: 24 additions & 12 deletions packages/@lwc/ssr-compiler/src/compile-js/generate-markup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ import type {
Program,
ImportDeclaration,
Property,
SimpleLiteral,
SimpleCallExpression,
Identifier,
MemberExpression,
} from 'estree';
import type { ComponentMetaState } from './types';

const bGenerateMarkup = esTemplate<ExportNamedDeclaration>`
const bGenerateMarkup = esTemplate`
export async function* generateMarkup(tagName, props, attrs, slotted) {
attrs = attrs ?? {};
${isNullableOf(is.expressionStatement)};
Expand All @@ -35,18 +39,18 @@ const bGenerateMarkup = esTemplate<ExportNamedDeclaration>`
yield tmplFn.stylesheetScopeTokenHostClass ?? '';
yield *__renderAttrs(instance, attrs)
yield '>';
yield* tmplFn(props, attrs, slotted, ${is.identifier}, instance);
yield* tmplFn(props, attrs, slotted, ${1}, instance);
yield \`</\${tagName}>\`;
}
`;
`<ExportNamedDeclaration>;

const bInsertFallbackTmplImport = esTemplate<ImportDeclaration>`
const bInsertFallbackTmplImport = esTemplate`
import { fallbackTmpl as __fallbackTmpl, renderAttrs as __renderAttrs } from '@lwc/ssr-runtime';
`;
`<ImportDeclaration>;

const bCreateReflectedPropArr = esTemplate<ExpressionStatement>`
const bCreateReflectedPropArr = esTemplate`
const __REFLECTED_PROPS__ = ${is.arrayExpression};
`;
`<ExpressionStatement>;

function bReflectedAttrsObj(reflectedPropNames: (keyof typeof AriaPropNameToAttrNameMap)[]) {
// This will build getter properties for each reflected property. It'll look
Expand Down Expand Up @@ -135,12 +139,22 @@ export function addGenerateMarkupExport(

const classIdentifier = b.identifier(state.lwcClassName!);
const renderCall = hasRenderMethod
? b.callExpression(b.memberExpression(b.identifier('instance'), b.identifier('render')), [])
? (b.callExpression(
b.memberExpression(b.identifier('instance'), b.identifier('render')),
[]
) as SimpleCallExpression & {
callee: MemberExpression & { property: Identifier & { name: 'render' } };
})
wjhsf marked this conversation as resolved.
Show resolved Hide resolved
: b.identifier('tmpl');

if (!tmplExplicitImports) {
const defaultTmplPath = filename.replace(/\.js$/, '.html');
program.body.unshift(bImportDeclaration(b.identifier('tmpl'), b.literal(defaultTmplPath)));
program.body.unshift(
bImportDeclaration(
b.identifier('tmpl'),
b.literal(defaultTmplPath) as SimpleLiteral & { value: string }
wjhsf marked this conversation as resolved.
Show resolved Hide resolved
)
);
}

let attrsAugmentation: ExpressionStatement | null = null;
Expand All @@ -153,7 +167,5 @@ export function addGenerateMarkupExport(

program.body.unshift(bInsertFallbackTmplImport());
program.body.push(bCreateReflectedPropArr(reflectedPropArr));
program.body.push(
bGenerateMarkup(attrsAugmentation, classIdentifier, renderCall, classIdentifier)
);
program.body.push(bGenerateMarkup(attrsAugmentation, classIdentifier, renderCall));
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,29 @@ import { builders as b } from 'estree-toolkit/dist/builders';
import { esTemplate } from '../estemplate';
import type { BlockStatement, ExportNamedDeclaration, Program, VariableDeclaration } from 'estree';

const bStylesheetTokenDeclaration = esTemplate<VariableDeclaration>`
const bStylesheetTokenDeclaration = esTemplate`
const stylesheetScopeToken = '${is.literal}';
`;
`<VariableDeclaration>;

const bAdditionalDeclarations = [
esTemplate<VariableDeclaration>`
esTemplate`
const hasScopedStylesheets = defaultScopedStylesheets && defaultScopedStylesheets.length > 0;
`,
esTemplate<ExportNamedDeclaration>`
`<VariableDeclaration>,
esTemplate`
const stylesheetScopeTokenClass = hasScopedStylesheets ? \` class="\${stylesheetScopeToken}"\` : '';
`,
esTemplate<ExportNamedDeclaration>`
`<ExportNamedDeclaration>,
esTemplate`
const stylesheetScopeTokenHostClass = hasScopedStylesheets ? \` class="\${stylesheetScopeToken}-host"\` : '';
`,
esTemplate<ExportNamedDeclaration>`
`<ExportNamedDeclaration>,
esTemplate`
const stylesheetScopeTokenClassPrefix = hasScopedStylesheets ? (stylesheetScopeToken + ' ') : '';
`,
`<ExportNamedDeclaration>,
];

// Scope tokens are associated with a given template. This is assigned here so that it can be used in `generateMarkup`.
const tmplAssignmentBlock = esTemplate<BlockStatement>`
const tmplAssignmentBlock = esTemplate`
${is.identifier}.stylesheetScopeTokenHostClass = stylesheetScopeTokenHostClass;
`;
`<BlockStatement>;

export function addScopeTokenDeclarations(
program: Program,
Expand Down
8 changes: 4 additions & 4 deletions packages/@lwc/ssr-compiler/src/compile-js/stylesheets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import type { NodePath } from 'estree-toolkit';
import type { ImportDeclaration } from 'estree';
import type { ComponentMetaState } from './types';

const bDefaultStyleImport = esTemplate<ImportDeclaration>`
const bDefaultStyleImport = esTemplate`
import defaultStylesheets from '${is.literal}';
`;
`<ImportDeclaration>;

const bDefaultScopedStyleImport = esTemplate<ImportDeclaration>`
const bDefaultScopedStyleImport = esTemplate`
import defaultScopedStylesheets from '${is.literal}';
`;
`<ImportDeclaration>;

export function catalogStyleImport(path: NodePath<ImportDeclaration>, state: ComponentMetaState) {
const specifier = path.node!.specifiers[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import type {
} from '@lwc/template-compiler';
import type { Transformer } from './types';

const bYieldFromChildGenerator = esTemplateWithYield<EsBlockStatement>`
const bYieldFromChildGenerator = esTemplateWithYield`
{
const childProps = ${is.objectExpression};
const childAttrs = ${is.objectExpression};
Expand All @@ -34,7 +34,7 @@ const bYieldFromChildGenerator = esTemplateWithYield<EsBlockStatement>`
};
yield* ${is.identifier}(${is.literal}, childProps, childAttrs, childSlottedContentGenerator);
}
`;
`<EsBlockStatement>;

const bImportGenerateMarkup = (localName: string, importPath: string) =>
b.importDeclaration(
Expand Down
8 changes: 4 additions & 4 deletions packages/@lwc/ssr-compiler/src/compile-template/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import type {
import type { Transformer } from './types';

const bYield = (expr: EsExpression) => b.expressionStatement(b.yieldExpression(expr));
const bConditionalLiveYield = esTemplateWithYield<EsBlockStatement>`
const bConditionalLiveYield = esTemplateWithYield`
{
const prefix = (${/* isClass */ is.literal} && stylesheetScopeTokenClassPrefix) || '';
const attrOrPropValue = ${is.expression};
Expand All @@ -48,14 +48,14 @@ const bConditionalLiveYield = esTemplateWithYield<EsBlockStatement>`
}
}
}
`;
`<EsBlockStatement>;

const bStringLiteralYield = esTemplateWithYield<EsBlockStatement>`
const bStringLiteralYield = esTemplateWithYield`
{
const prefix = (${/* isClass */ is.literal} && stylesheetScopeTokenClassPrefix) || '';
yield ' ' + ${is.literal} + '="' + prefix + "${is.literal}" + '"'
}
`;
`<EsBlockStatement>;

function yieldAttrOrPropLiteralValue(
name: string,
Expand Down
8 changes: 2 additions & 6 deletions packages/@lwc/ssr-compiler/src/compile-template/for-each.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import type {
Expression as EsExpression,
ForOfStatement as EsForOfStatement,
Identifier as EsIdentifier,
Statement as EsStatement,
MemberExpression as EsMemberExpression,
} from 'estree';
import type { Transformer } from './types';
Expand All @@ -29,14 +28,11 @@ function getRootIdentifier(node: EsMemberExpression): EsIdentifier | null {
return is.identifier(rootMemberExpression?.object) ? rootMemberExpression.object : null;
}

const bForOfYieldFrom = esTemplate<
EsForOfStatement,
[EsIdentifier, EsIdentifier, EsExpression, EsStatement[]]
>`
const bForOfYieldFrom = esTemplate`
for (let [${is.identifier}, ${is.identifier}] of Object.entries(${is.expression} ?? {})) {
${is.statement};
}
`;
`<EsForOfStatement>;

export const ForEach: Transformer<IrForEach> = function ForEach(node, cxt): EsForOfStatement[] {
const forItemId = node.item.name;
Expand Down
9 changes: 4 additions & 5 deletions packages/@lwc/ssr-compiler/src/compile-template/for-of.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import type {
Expression as EsExpression,
ForOfStatement as EsForOfStatement,
Identifier as EsIdentifier,
Statement as EsStatement,
MemberExpression as EsMemberExpression,
ImportDeclaration as EsImportDeclaration,
} from 'estree';
Expand All @@ -30,15 +29,15 @@ function getRootIdentifier(node: EsMemberExpression): EsIdentifier | null {
return is.identifier(rootMemberExpression?.object) ? rootMemberExpression.object : null;
}

const bForOfYieldFrom = esTemplate<EsForOfStatement, [EsIdentifier, EsExpression, EsStatement[]]>`
const bForOfYieldFrom = esTemplate`
for (let ${is.identifier} of toIteratorDirective(${is.expression} ?? [])) {
${is.statement};
}
`;
`<EsForOfStatement>;

const bToIteratorDirectiveImport = esTemplate<EsImportDeclaration>`
const bToIteratorDirectiveImport = esTemplate`
import { toIteratorDirective } from '@lwc/ssr-runtime';
`;
`<EsImportDeclaration>;

export const ForOf: Transformer<IrForOf> = function ForEach(node, cxt): EsForOfStatement[] {
const id = node.iterator.name;
Expand Down
Loading
Loading