From b2138b52b29f542554a097a4cb9a7f1774240445 Mon Sep 17 00:00:00 2001 From: Gaurav Kochar Date: Mon, 19 May 2025 10:42:43 +0530 Subject: [PATCH] feat(ssr): make SSR compiler recognize lwc:on directive Make SSR compiler recognize lwc:on directive. Also adds snapshot and hydration tests to verify lwc:on used in SSR context --- .../src/__tests__/fixtures.spec.ts | 1 + .../src/__tests__/fixtures/lwc-on/config.json | 3 +++ .../src/__tests__/fixtures/lwc-on/error.txt | 0 .../__tests__/fixtures/lwc-on/expected.html | 7 ++++++ .../lwc-on/modules/x/lwc-on/lwc-on.html | 3 +++ .../lwc-on/modules/x/lwc-on/lwc-on.js | 12 +++++++++ .../scripts/karma-plugins/hydration-tests.js | 1 + .../directives/lwc-on/index.spec.js | 20 +++++++++++++++ .../directives/lwc-on/x/main/main.html | 3 +++ .../directives/lwc-on/x/main/main.js | 25 +++++++++++++++++++ .../src/__tests__/fixtures.spec.ts | 1 + .../src/compile-template/index.ts | 1 + 12 files changed, 77 insertions(+) create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html create mode 100644 packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html create mode 100644 packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts index 30442d190d..14a05b484a 100755 --- a/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/engine-server/src/__tests__/fixtures.spec.ts @@ -79,6 +79,7 @@ async function compileFixture({ pluginVirtual(`export { default } from "${entry}";`, input), lwcRollupPlugin({ enableDynamicComponents: true, + enableLwcOn: true, experimentalDynamicComponent: { loader: path.join(__dirname, './utils/custom-loader.js'), strictSpecifier: false, diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json new file mode 100644 index 0000000000..1b68decbe9 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/config.json @@ -0,0 +1,3 @@ +{ + "entry": "x/lwc-on" +} diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/error.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html new file mode 100644 index 0000000000..dae22dad95 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/expected.html @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html new file mode 100644 index 0000000000..10042889ff --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.html @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js new file mode 100644 index 0000000000..e7c5cfb4c4 --- /dev/null +++ b/packages/@lwc/engine-server/src/__tests__/fixtures/lwc-on/modules/x/lwc-on/lwc-on.js @@ -0,0 +1,12 @@ +import { LightningElement } from 'lwc'; + +export default class LwcOn extends LightningElement { + eventListeners = { + click: () => { + console.log('click'); + }, + foo: () => { + console.log('foo'); + }, + }; +} diff --git a/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js b/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js index e1135eaeb7..cfa37e6f95 100644 --- a/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js +++ b/packages/@lwc/integration-karma/scripts/karma-plugins/hydration-tests.js @@ -71,6 +71,7 @@ async function getCompiledModule(dirName, compileForSSR) { strict: true, }, enableDynamicComponents: true, + enableLwcOn: true, enableStaticContentOptimization: !DISABLE_STATIC_CONTENT_OPTIMIZATION, experimentalDynamicDirective: true, }), diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js new file mode 100644 index 0000000000..d9cb0c0ad8 --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/index.spec.js @@ -0,0 +1,20 @@ +export default { + props: {}, + snapshot(target) { + const div = target.shadowRoot.querySelector('div'); + + return { + div, + }; + }, + test(target, snapshots) { + const snapshotAfterHydration = this.snapshot(target); + expect(snapshotAfterHydration.div).toBe(snapshots.div); + + // verify handler + snapshotAfterHydration.div.click(); + expect(target.timesClickedHandlerIsExecuted).toBe(1); + snapshotAfterHydration.div.dispatchEvent(new CustomEvent('foo')); + expect(target.timesFooHandlerIsExecuted).toBe(1); + }, +}; diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html new file mode 100644 index 0000000000..cabec61e8b --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.html @@ -0,0 +1,3 @@ + diff --git a/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js new file mode 100644 index 0000000000..4464d2fd7b --- /dev/null +++ b/packages/@lwc/integration-karma/test-hydration/directives/lwc-on/x/main/main.js @@ -0,0 +1,25 @@ +import { LightningElement, api } from 'lwc'; + +export default class Main extends LightningElement { + _clickedHandlerCounter = 0; + _fooHandlerCounter = 0; + + @api + get timesClickedHandlerIsExecuted() { + return this._clickedHandlerCounter; + } + + @api + get timesFooHandlerIsExecuted() { + return this._fooHandlerCounter; + } + + eventListeners = { + click: function () { + this._clickedHandlerCounter++; + }, + foo: function () { + this._fooHandlerCounter++; + }, + }; +} diff --git a/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts b/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts index 82be0af3c0..8c39d7ba7c 100644 --- a/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts +++ b/packages/@lwc/ssr-compiler/src/__tests__/fixtures.spec.ts @@ -65,6 +65,7 @@ async function compileFixture({ entry, dirname }: { entry: string; dirname: stri targetSSR: true, ssrMode: SSR_MODE, enableDynamicComponents: true, + enableLwcOn: true, // TODO [#3331]: remove usage of lwc:dynamic in 246 experimentalDynamicDirective: true, modules: [{ dir: modulesDir }], diff --git a/packages/@lwc/ssr-compiler/src/compile-template/index.ts b/packages/@lwc/ssr-compiler/src/compile-template/index.ts index 74cc04092a..47b827528d 100644 --- a/packages/@lwc/ssr-compiler/src/compile-template/index.ts +++ b/packages/@lwc/ssr-compiler/src/compile-template/index.ts @@ -89,6 +89,7 @@ export default function compileTemplate( experimentalComputedMemberExpression: options.experimentalComputedMemberExpression, experimentalComplexExpressions: options.experimentalComplexExpressions, enableDynamicComponents: options.enableDynamicComponents, + enableLwcOn: options.enableLwcOn, preserveHtmlComments: options.preserveHtmlComments, enableStaticContentOptimization: options.enableStaticContentOptimization, instrumentation: options.instrumentation,