diff --git a/site/content/docs/03-run-time.md b/site/content/docs/03-run-time.md index 42a99bea70e6..c1fca56e9f11 100644 --- a/site/content/docs/03-run-time.md +++ b/site/content/docs/03-run-time.md @@ -1051,12 +1051,14 @@ A server-side component exposes a `render` method that can be called with option You can import a Svelte component directly into Node using [`svelte/register`](docs#svelte_register). +`renderedComponents` contains an array of filenames of components that were rendered during SSR. The filenames come from `svelte.compile({filename: '...' })`, which is generally done behind the scenes by your bundler (eg: Rollup). You can match these file names to your asset modules in order to preload asynchronous components that will be required on the client-side ahead-of-time. + ```js require('svelte/register'); const App = require('./App.svelte').default; -const { head, html, css } = App.render({ +const { head, html, css, renderedComponents } = App.render({ answer: 42 }); ``` diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index ff45abd78b05..dd9893601ba7 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -134,6 +134,7 @@ export default function ssr( instance_javascript, ...parent_bindings, css.code && b`$$result.css.add(#css);`, + options.filename && b`$$result.renderedComponents.add('${options.filename}');`, main ].filter(Boolean); diff --git a/src/runtime/internal/ssr.ts b/src/runtime/internal/ssr.ts index 6f1cdedd8ac1..203410dd7970 100644 --- a/src/runtime/internal/ssr.ts +++ b/src/runtime/internal/ssr.ts @@ -107,7 +107,8 @@ export function create_ssr_component(fn) { map: null; code: string; }>; - } = { title: '', head: '', css: new Set() }; + renderedComponents: Set; + } = { title: '', head: '', css: new Set(), renderedComponents: new Set() }; const html = $$render(result, props, {}, options); @@ -119,7 +120,8 @@ export function create_ssr_component(fn) { code: Array.from(result.css).map(css => css.code).join('\n'), map: null // TODO }, - head: result.title + result.head + head: result.title + result.head, + renderedComponents: Array.from(result.renderedComponents) }; }, diff --git a/test/server-side-rendering/index.ts b/test/server-side-rendering/index.ts index ef2a88ecbe72..ab11dab443b4 100644 --- a/test/server-side-rendering/index.ts +++ b/test/server-side-rendering/index.ts @@ -37,7 +37,6 @@ describe('ssr', () => { if (dir[0] === '.') return; const config = loadConfig(`${__dirname}/samples/${dir}/_config.js`); - // add .solo to a sample directory name to only run that test, or // .show to always show the output. or both const solo = config.solo || /\.solo/.test(dir); @@ -76,7 +75,11 @@ describe('ssr', () => { if (css.code) fs.writeFileSync(`${dir}/_actual.css`, css.code); try { - assert.htmlEqual(html, expectedHtml); + if (config.testForRenderedComponents) { + assert.ok(rendered.renderedComponents[0].includes('main.svelte')); + } else { + assert.htmlEqual(html, expectedHtml); + } } catch (error) { if (shouldUpdateExpected()) { fs.writeFileSync(`${dir}/_expected.html`, html); diff --git a/test/server-side-rendering/samples/renderedComponents/_config.js b/test/server-side-rendering/samples/renderedComponents/_config.js new file mode 100644 index 000000000000..b9b3278d3b6d --- /dev/null +++ b/test/server-side-rendering/samples/renderedComponents/_config.js @@ -0,0 +1,3 @@ +export default { + testForRenderedComponents: true +}; \ No newline at end of file diff --git a/test/server-side-rendering/samples/renderedComponents/_expected.html b/test/server-side-rendering/samples/renderedComponents/_expected.html new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/test/server-side-rendering/samples/renderedComponents/main.svelte b/test/server-side-rendering/samples/renderedComponents/main.svelte new file mode 100644 index 000000000000..e69de29bb2d1