@@ -18,7 +18,6 @@ lwcSsr.setHooks({
1818} ) ;
1919
2020const ROOT_DIR = path . join ( import . meta. dirname , '../..' ) ;
21-
2221const COMPONENT_NAME = 'x-main' ;
2322const COMPONENT_ENTRYPOINT = 'x/main/main.js' ;
2423
@@ -74,25 +73,22 @@ async function compileModule(input, targetSSR, format) {
7473}
7574
7675/**
77- * This is the function that takes SSR bundle code and test config, constructs a script that will
78- * run in a separate JS runtime environment with its own global scope. The `context` object
79- * (defined at the top of this file) is passed in as the global scope for that script. The script
80- * runs, utilizing the `LWC` object that we've attached to the global scope, it sets a
81- * new value (the rendered markup) to `globalThis.moduleOutput`, which corresponds to
82- * `context.moduleOutput in this file's scope.
83- *
84- * So, script runs, generates markup, & we get that markup out and return it for use
85- * in client-side tests.
76+ * This function takes a path to a component definition and a config file and returns the
77+ * SSR-generated markup for the component. It does so by compiling the component and then
78+ * running a script in a separate JS runtime environment to render it.
8679 */
87- async function getSsrCode ( moduleCode , filePath ) {
88- // LWC itself requires configuration before each test (`setHooks` and
89- // `setFeatureFlagForTest`). Ideally, this would be done in pure isolation,
90- // but getting that set up for `vm.Script`/`vm.Module` is non-trivial.
91- // Instead, we inject a shared LWC that gets configured outside the script.
80+ async function getSsrMarkup ( componentEntrypoint , configPath ) {
81+ const componentIife = await compileModule ( componentEntrypoint , ! ENGINE_SERVER , 'iife' ) ;
82+ // To minimize the amount of code in the generated script, ideally we'd do `import Component`
83+ // and delegate the bundling to the loader. However, that's complicated to configure and using
84+ // imports with vm.Script/vm.Module is still experimental, so we use an IIFE for simplicity.
85+ // Additionally, we could import LWC, but the framework requires configuration before each test
86+ // (setHooks/setFeatureFlagForTest), so instead we configure it once in the top-level context
87+ // and inject it as a global variable.
9288 const script = new vm . Script (
9389 `(async () => {
94- const {default: config} = await import('./${ filePath } ');
95- ${ moduleCode /* var Component = ... */ }
90+ const {default: config} = await import('./${ configPath } ');
91+ ${ componentIife /* var Component = ... */ }
9692 return LWC.renderComponent(
9793 '${ COMPONENT_NAME } ',
9894 Component,
@@ -102,7 +98,7 @@ async function getSsrCode(moduleCode, filePath) {
10298 );
10399 })()` ,
104100 {
105- filename : `[SSR] ${ filePath } ` ,
101+ filename : `[SSR] ${ configPath } ` ,
106102 importModuleDynamically : vm . constants . USE_MAIN_CONTEXT_DEFAULT_LOADER ,
107103 }
108104 ) ;
@@ -133,11 +129,9 @@ async function wrapHydrationTest(configPath) {
133129
134130 const suiteDir = path . dirname ( configPath ) ;
135131 const componentEntrypoint = path . join ( suiteDir , COMPONENT_ENTRYPOINT ) ;
136- // You can add an `.only` file alongside an `index.spec.js` file to make it `fdescribe()`
132+ // You can add an `.only` file alongside an `index.spec.js` file to make the test focused
137133 const onlyFileExists = await existsUp ( suiteDir , '.only' ) ;
138-
139- const componentDefSSR = await compileModule ( componentEntrypoint , ! ENGINE_SERVER , 'iife' ) ;
140- const ssrOutput = await getSsrCode ( componentDefSSR , configPath ) ;
134+ const ssrOutput = await getSsrMarkup ( componentEntrypoint , configPath ) ;
141135
142136 return `
143137 import { runTest } from '/helpers/test-hydrate.js';
@@ -166,7 +160,7 @@ export default {
166160 if ( ctx . path . endsWith ( '.spec.js' ) && ! ctx . query . original ) {
167161 return await wrapHydrationTest ( ctx . path . slice ( 1 ) ) ; // remove leading /
168162 } else if ( ctx . path . endsWith ( '/' + COMPONENT_ENTRYPOINT ) ) {
169- return compileModule ( ctx . path . slice ( 1 ) /* remove leading / */ , false , 'esm' ) ;
163+ return await compileModule ( ctx . path . slice ( 1 ) /* remove leading / */ , false , 'esm' ) ;
170164 }
171165 } ,
172166} ;
0 commit comments