Skip to content

Commit 785479b

Browse files
authored
chore: use __lwc for transmogrified function names (#5278)
* refactor(ssr): use `__lwcTmpl` instead of `tmpl` * refactor(ssr): use `__lwcGenerateSlottedContent` instead of `generateSlottedContent` * refactor(ssr): use `__lwcGenerateMarkup` instead of `generateMarkup` * refactor: why use two regex when one regex do trick?
1 parent 2bdd109 commit 785479b

File tree

7 files changed

+35
-42
lines changed

7 files changed

+35
-42
lines changed

packages/@lwc/ssr-compiler/src/__tests__/compilation.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ describe('component compilation', () => {
3131
`;
3232
const filename = path.resolve('component.js');
3333
const { code } = compileComponentForSSR(src, filename, {});
34-
expect(code).toContain('import tmpl from "./component.html"');
34+
expect(code).toContain('import __lwcTmpl from "./component.html"');
3535
});
3636
test('explicit templates imports do not use full file paths', () => {
3737
const src = `
@@ -59,7 +59,7 @@ describe('component compilation', () => {
5959
`;
6060
const filename = path.resolve('component.ts');
6161
const { code } = compileComponentForSSR(src, filename, {});
62-
expect(code).toContain('import tmpl from "./component.html"');
62+
expect(code).toContain('import __lwcTmpl from "./component.html"');
6363
});
6464

6565
describe('wire decorator', () => {

packages/@lwc/ssr-compiler/src/__tests__/transmogrify.spec.ts

+16-16
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { transmogrify } from '../transmogrify';
55
import type { Program as EsProgram } from 'estree';
66

77
const COMPILED_CMP = `
8-
async function* tmpl(props, attrs, slottedContent, Cmp, instance) {
8+
async function* __lwcTmpl(props, attrs, slottedContent, Cmp, instance) {
99
yield "<p";
1010
yield stylesheetScopeTokenClass;
1111
yield ">Hello</p>";
@@ -27,7 +27,7 @@ const COMPILED_CMP = `
2727
}
2828
}
2929
const __REFLECTED_PROPS__ = [];
30-
async function* generateMarkup(tagName, props, attrs, slotted) {
30+
async function* __lwcGenerateMarkup(tagName, props, attrs, slotted) {
3131
attrs = attrs ?? ({});
3232
const instance = new Basic({
3333
tagName: tagName.toUpperCase()
@@ -65,10 +65,10 @@ describe('transmogrify', () => {
6565
});
6666

6767
describe('in sync mode', () => {
68-
test('generateMarkup is transformed into sync mode', () => {
69-
expect(COMPILED_CMP_SYNC).not.toContain('async function* generateMarkup');
70-
expect(COMPILED_CMP_SYNC).not.toContain('async function generateMarkup');
71-
expect(COMPILED_CMP_SYNC).toContain('function generateMarkup($$emit');
68+
test('__lwcGenerateMarkup is transformed into sync mode', () => {
69+
expect(COMPILED_CMP_SYNC).not.toContain('async function* __lwcGenerateMarkup');
70+
expect(COMPILED_CMP_SYNC).not.toContain('async function __lwcGenerateMarkup');
71+
expect(COMPILED_CMP_SYNC).toContain('function __lwcGenerateMarkup($$emit');
7272

7373
expect(COMPILED_CMP_SYNC).not.toContain('yield* renderAttrs');
7474
expect(COMPILED_CMP_SYNC).toContain('renderAttrs($$emit');
@@ -78,10 +78,10 @@ describe('transmogrify', () => {
7878
expect(COMPILED_CMP_SYNC).toContain('$$emit(">")');
7979
});
8080

81-
test('tmpl is transformed into sync mode', () => {
82-
expect(COMPILED_CMP_SYNC).not.toContain('async function* tmpl');
83-
expect(COMPILED_CMP_SYNC).not.toContain('async function tmpl');
84-
expect(COMPILED_CMP_SYNC).toContain('function tmpl($$emit');
81+
test('__lwcTmpl is transformed into sync mode', () => {
82+
expect(COMPILED_CMP_SYNC).not.toContain('async function* __lwcTmpl');
83+
expect(COMPILED_CMP_SYNC).not.toContain('async function __lwcTmpl');
84+
expect(COMPILED_CMP_SYNC).toContain('function __lwcTmpl($$emit');
8585

8686
expect(COMPILED_CMP_SYNC).not.toContain('yield "<p"');
8787
expect(COMPILED_CMP_SYNC).toContain('$$emit("<p")');
@@ -102,9 +102,9 @@ describe('transmogrify', () => {
102102
});
103103

104104
describe('in async mode', () => {
105-
test('generateMarkup is transformed into async mode', () => {
106-
expect(COMPILED_CMP_ASYNC).not.toContain('async function* generateMarkup');
107-
expect(COMPILED_CMP_ASYNC).toContain('async function generateMarkup($$emit');
105+
test('__lwcGenerateMarkup is transformed into async mode', () => {
106+
expect(COMPILED_CMP_ASYNC).not.toContain('async function* __lwcGenerateMarkup');
107+
expect(COMPILED_CMP_ASYNC).toContain('async function __lwcGenerateMarkup($$emit');
108108

109109
expect(COMPILED_CMP_ASYNC).not.toContain('yield* renderAttrs');
110110
expect(COMPILED_CMP_ASYNC).toContain('renderAttrs($$emit');
@@ -114,9 +114,9 @@ describe('transmogrify', () => {
114114
expect(COMPILED_CMP_ASYNC).toContain('$$emit(">")');
115115
});
116116

117-
test('tmpl is transformed into async mode', () => {
118-
expect(COMPILED_CMP_ASYNC).not.toContain('async function* tmpl');
119-
expect(COMPILED_CMP_ASYNC).toContain('async function tmpl($$emit');
117+
test('__lwcTmpl is transformed into async mode', () => {
118+
expect(COMPILED_CMP_ASYNC).not.toContain('async function* __lwcTmpl');
119+
expect(COMPILED_CMP_ASYNC).toContain('async function __lwcTmpl($$emit');
120120

121121
expect(COMPILED_CMP_ASYNC).not.toContain('yield "<p"');
122122
expect(COMPILED_CMP_ASYNC).toContain('$$emit("<p")');

packages/@lwc/ssr-compiler/src/compile-js/generate-markup.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const bGenerateMarkup = esTemplate`
2626
configurable: false,
2727
enumerable: false,
2828
writable: false,
29-
value: async function* generateMarkup(
29+
value: async function* __lwcGenerateMarkup(
3030
// The $$emit function is magically inserted here
3131
tagName,
3232
props,
@@ -139,7 +139,7 @@ export function addGenerateMarkupFunction(
139139
let exposeTemplateBlock: IfStatement | null = null;
140140
if (!tmplExplicitImports) {
141141
const defaultTmplPath = `./${pathParse(filename).name}.html`;
142-
const tmplVar = b.identifier('tmpl');
142+
const tmplVar = b.identifier('__lwcTmpl');
143143
program.body.unshift(bImportDeclaration({ default: tmplVar.name }, defaultTmplPath));
144144
program.body.unshift(
145145
bImportDeclaration({ SYMBOL__DEFAULT_TEMPLATE: '__SYMBOL__DEFAULT_TEMPLATE' })

packages/@lwc/ssr-compiler/src/compile-js/stylesheet-scope-token.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@ export function addScopeTokenDeclarations(
4040
bHasScopedStylesheetsDeclaration()
4141
);
4242

43-
program.body.push(...tmplAssignmentBlock(b.identifier('tmpl')));
43+
program.body.push(...tmplAssignmentBlock(b.identifier('__lwcTmpl')));
4444
}

packages/@lwc/ssr-compiler/src/compile-template/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import type {
2323

2424
// TODO [#4663]: Render mode mismatch between template and compiler should throw.
2525
const bExportTemplate = esTemplate`
26-
export default async function* tmpl(
26+
export default async function* __lwcTmpl(
2727
// This is where $$emit comes from
2828
shadowSlottedContent,
2929
lightSlottedContent,

packages/@lwc/ssr-compiler/src/compile-template/transformers/component/slotted-content.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import type { TransformerContext } from '../../types';
3838

3939
const bGenerateSlottedContent = esTemplateWithYield`
4040
const shadowSlottedContent = ${/* hasShadowSlottedContent */ is.literal}
41-
? async function* generateSlottedContent(contextfulParent) {
41+
? async function* __lwcGenerateSlottedContent(contextfulParent) {
4242
// The 'contextfulParent' variable is shadowed here so that a contextful relationship
4343
// is established between components rendered in slotted content & the "parent"
4444
// component that contains the <slot>.
@@ -72,11 +72,11 @@ const bGenerateSlottedContent = esTemplateWithYield`
7272
${/* scoped slot addLightContent statements */ is.expressionStatement}
7373
`<EsStatement[]>;
7474

75-
// Note that this function name (`generateSlottedContent`) does not need to be scoped even though
75+
// Note that this function name (`__lwcGenerateSlottedContent`) does not need to be scoped even though
7676
// it may be repeated multiple times in the same scope, because it's a function _expression_ rather
7777
// than a function _declaration_, so it isn't available to be referenced anywhere.
7878
const bAddSlottedContent = esTemplate`
79-
addSlottedContent(${/* slot name */ is.expression} ?? "", async function* generateSlottedContent(contextfulParent, ${
79+
addSlottedContent(${/* slot name */ is.expression} ?? "", async function* __lwcGenerateSlottedContent(contextfulParent, ${
8080
/* scoped slot data variable */ isNullableOf(is.identifier)
8181
}, slotAttributeValue) {
8282
// FIXME: make validation work again

packages/@lwc/ssr-compiler/src/transmogrify.ts

+10-17
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,24 @@ interface TransmogrificationState {
1919
export type Visitors = Parameters<typeof traverse<Node, TransmogrificationState>>[1];
2020

2121
const EMIT_IDENT = b.identifier('$$emit');
22+
/** Function names that may be transmogrified. All should start with `__lwc`. */
2223
// Rollup may rename variables to prevent shadowing. When it does, it uses the format `foo$0`, `foo$1`, etc.
23-
const TMPL_FN_PATTERN = /tmpl($\d+)?/;
24-
const GEN_MARKUP_OR_GEN_SLOTTED_CONTENT_PATTERN =
25-
/(?:generateMarkup|generateSlottedContent)($\d+)?/;
24+
const TRANSMOGRIFY_TARGET = /^__lwc(GenerateMarkup|GenerateSlottedContent|Tmpl)(?:\$\d+)?$/;
2625

27-
const isWithinFn = (pattern: RegExp, nodePath: NodePath): boolean => {
26+
const isWithinFn = (nodePath: NodePath): boolean => {
2827
const { node } = nodePath;
2928
if (!node) {
3029
return false;
3130
}
3231
if (
3332
(node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression') &&
3433
node.id &&
35-
pattern.test(node.id.name)
34+
TRANSMOGRIFY_TARGET.test(node.id.name)
3635
) {
3736
return true;
3837
}
3938
if (nodePath.parentPath) {
40-
return isWithinFn(pattern, nodePath.parentPath);
39+
return isWithinFn(nodePath.parentPath);
4140
}
4241
return false;
4342
};
@@ -57,10 +56,7 @@ const visitors: Visitors = {
5756
// Component authors might conceivably use async generator functions in their own code. Therefore,
5857
// when traversing & transforming written+generated code, we need to disambiguate generated async
5958
// generator functions from those that were written by the component author.
60-
if (
61-
!isWithinFn(GEN_MARKUP_OR_GEN_SLOTTED_CONTENT_PATTERN, path) &&
62-
!isWithinFn(TMPL_FN_PATTERN, path)
63-
) {
59+
if (!isWithinFn(path)) {
6460
return;
6561
}
6662
node.generator = false;
@@ -76,10 +72,7 @@ const visitors: Visitors = {
7672
// Component authors might conceivably use generator functions within their own code. Therefore,
7773
// when traversing & transforming written+generated code, we need to disambiguate generated yield
7874
// expressions from those that were written by the component author.
79-
if (
80-
!isWithinFn(TMPL_FN_PATTERN, path) &&
81-
!isWithinFn(GEN_MARKUP_OR_GEN_SLOTTED_CONTENT_PATTERN, path)
82-
) {
75+
if (!isWithinFn(path)) {
8376
return;
8477
}
8578

@@ -152,7 +145,7 @@ const visitors: Visitors = {
152145
* Is compiled into the following JavaScript, intended for execution during SSR & stripped down
153146
* for the purposes of this example:
154147
*
155-
* async function* tmpl(props, attrs, slottedContent, Cmp, instance) {
148+
* async function* __lwcTmpl(props, attrs, slottedContent, Cmp, instance) {
156149
* yield '<div>foobar</div>';
157150
* const childProps = {};
158151
* const childAttrs = {};
@@ -161,7 +154,7 @@ const visitors: Visitors = {
161154
*
162155
* When transmogrified in async-mode, the above generated template function becomes the following:
163156
*
164-
* async function tmpl($$emit, props, attrs, slottedContent, Cmp, instance) {
157+
* async function __lwcTmpl($$emit, props, attrs, slottedContent, Cmp, instance) {
165158
* $$emit('<div>foobar</div>');
166159
* const childProps = {};
167160
* const childAttrs = {};
@@ -170,7 +163,7 @@ const visitors: Visitors = {
170163
*
171164
* When transmogrified in sync-mode, the template function becomes the following:
172165
*
173-
* function tmpl($$emit, props, attrs, slottedContent, Cmp, instance) {
166+
* function __lwcTmpl($$emit, props, attrs, slottedContent, Cmp, instance) {
174167
* $$emit('<div>foobar</div>');
175168
* const childProps = {};
176169
* const childAttrs = {};

0 commit comments

Comments
 (0)