diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index e256ba78fb..670aa9baeb 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -198,7 +198,7 @@ export default function ssr( instance_javascript, ...parent_bindings, css.code && b`$$result.css.add(#css);`, - main + b`return @no_current_component(() => { ${main} });` ].filter(Boolean); const css_sourcemap_enabled = check_enable_sourcemap(options.enableSourcemap, 'css'); diff --git a/src/runtime/internal/Component.ts b/src/runtime/internal/Component.ts index 3e48010547..a642a56944 100644 --- a/src/runtime/internal/Component.ts +++ b/src/runtime/internal/Component.ts @@ -1,5 +1,5 @@ import { add_render_callback, flush, schedule_update, dirty_components } from './scheduler'; -import { current_component, set_current_component } from './lifecycle'; +import { current_component, no_current_component, set_current_component } from './lifecycle'; import { blank_object, is_empty, is_function, run, run_all, noop } from './utils'; import { children, detach, start_hydrating, end_hydrating } from './dom'; import { transition_in } from './transitions'; @@ -152,26 +152,29 @@ export function init(component, options, instance, create_fragment, not_equal, p ready = true; run_all($$.before_update); - // `false` as a special case of no DOM component - $$.fragment = create_fragment ? create_fragment($$.ctx) : false; - - if (options.target) { - if (options.hydrate) { - start_hydrating(); - const nodes = children(options.target); - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment!.l(nodes); - nodes.forEach(detach); - } else { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - $$.fragment && $$.fragment!.c(); - } + no_current_component(() => { + // `false` as a special case of no DOM component + $$.fragment = create_fragment ? create_fragment($$.ctx) : false; + + + if (options.target) { + if (options.hydrate) { + start_hydrating(); + const nodes = children(options.target); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment!.l(nodes); + nodes.forEach(detach); + } else { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + $$.fragment && $$.fragment!.c(); + } - if (options.intro) transition_in(component.$$.fragment); - mount_component(component, options.target, options.anchor, options.customElement); - end_hydrating(); - flush(); - } + if (options.intro) transition_in(component.$$.fragment); + mount_component(component, options.target, options.anchor, options.customElement); + end_hydrating(); + flush(); + } + }); set_current_component(parent_component); } diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index fbbeca9a67..ae024c52d0 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -11,6 +11,14 @@ export function get_current_component() { return current_component; } +export function no_current_component(callback: () => void) { + const old_current_component = current_component; + current_component = undefined; + const value = callback(); + current_component = old_current_component; + return value; +} + export function beforeUpdate(fn: () => any) { get_current_component().$$.before_update.push(fn); } diff --git a/test/runtime/samples/context-api-in-element-1/_config.js b/test/runtime/samples/context-api-in-element-1/_config.js new file mode 100644 index 0000000000..79b5908ab7 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-1/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-1/main.svelte b/test/runtime/samples/context-api-in-element-1/main.svelte new file mode 100644 index 0000000000..584d2bb053 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-1/main.svelte @@ -0,0 +1,5 @@ + + +{getContext('test')} diff --git a/test/runtime/samples/context-api-in-element-2/_config.js b/test/runtime/samples/context-api-in-element-2/_config.js new file mode 100644 index 0000000000..79b5908ab7 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-2/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-2/main.svelte b/test/runtime/samples/context-api-in-element-2/main.svelte new file mode 100644 index 0000000000..c852c7f5d7 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-2/main.svelte @@ -0,0 +1,5 @@ + + +xxx diff --git a/test/runtime/samples/context-api-in-element-3/_config.js b/test/runtime/samples/context-api-in-element-3/_config.js new file mode 100644 index 0000000000..79b5908ab7 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-3/_config.js @@ -0,0 +1,3 @@ +export default { + error: 'Function called outside component initialization' +}; diff --git a/test/runtime/samples/context-api-in-element-3/main.svelte b/test/runtime/samples/context-api-in-element-3/main.svelte new file mode 100644 index 0000000000..04f969fff3 --- /dev/null +++ b/test/runtime/samples/context-api-in-element-3/main.svelte @@ -0,0 +1,5 @@ + + +{getContext('test')}