diff --git a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js index 90a693b99a..6d1de18708 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/transform-server.js @@ -6,7 +6,7 @@ import { walk } from 'zimmerframe'; import { set_scope } from '../../scope.js'; import { extract_identifiers } from '../../../utils/ast.js'; import * as b from '#compiler/builders'; -import { component_name, dev, filename } from '../../../state.js'; +import { component_name, custom_renderer, dev, filename } from '../../../state.js'; import { render_stylesheet } from '../css/index.js'; import { AssignmentExpression } from './visitors/AssignmentExpression.js'; import { AwaitBlock } from './visitors/AwaitBlock.js'; @@ -90,6 +90,19 @@ const template_visitors = { * @returns {ESTree.Program} */ export function server_component(analysis, options) { + // Components compiled with a custom renderer have no meaningful server + // representation — they only render on the client through the custom + // renderer — so we compile them down to a no-op. + if (custom_renderer) { + const component_function = b.function_declaration(b.id(analysis.name), [], b.block([])); + + return { + type: 'Program', + sourceType: 'module', + body: [b.export_default(component_function)] + }; + } + /** @type {ComponentServerTransformState} */ const state = { analysis, diff --git a/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_config.js b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_config.js new file mode 100644 index 0000000000..135918fc82 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_config.js @@ -0,0 +1,13 @@ +import { test } from '../../test'; + +export default test({ + compileOptions: { + experimental: { + // The actual renderer module is irrelevant for this snapshot — we only + // care that the server output is a no-op while the client output still + // imports/uses the custom renderer. Using a fixed path keeps the + // snapshot stable across machines. + customRenderer: 'my-custom-renderer' + } + } +}); diff --git a/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/client/main.svelte.js b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/client/main.svelte.js new file mode 100644 index 0000000000..b735c2dfa4 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/client/main.svelte.js @@ -0,0 +1,17 @@ +import $renderer from 'my-custom-renderer'; +import 'svelte/internal/disclose-version'; +import * as $ from 'svelte/internal/client'; + +var root = $.from_tree([['div', { class: 'greeting' }, ' ']]); + +export default function Main($$anchor, $$props) { + var $$pop_renderer = $.push_renderer($renderer); + let name = $.prop($$props, 'name', 3, 'world'); + var div = root(); + var text = $.child(div); + + $.reset(div); + $.template_effect(() => $.set_text(text, `Hello ${name() ?? ''}!`)); + $.append($$anchor, div); + $$pop_renderer(); +} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/server/main.svelte.js b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/server/main.svelte.js new file mode 100644 index 0000000000..2b19de8d86 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/_expected/server/main.svelte.js @@ -0,0 +1 @@ +export default function Main() {} \ No newline at end of file diff --git a/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/main.svelte b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/main.svelte new file mode 100644 index 0000000000..f54c1e4c81 --- /dev/null +++ b/packages/svelte/tests/snapshot/samples/custom-renderer-server-noop/main.svelte @@ -0,0 +1,5 @@ + + +
Hello {name}!