From bdc45fdf7f4ee9ddfcb0dc0e875ebaca68a4f0df Mon Sep 17 00:00:00 2001 From: Rich Harris <rich.harris@vercel.com> Date: Tue, 9 Jul 2024 15:43:57 -0700 Subject: [PATCH] breaking: rename `legacy.componentApi` to `compatibility.componentApi` (#12370) * breaking: rename `legacy.componentApi` to `compatibility.legacyComponent` closes #12112 * fix * rename to compatibility.componentApi * update changeset * tidy up * default to 5 --------- Co-authored-by: Simon Holthausen <simon.holthausen@vercel.com> --- .changeset/sour-tomatoes-knock.md | 5 +++++ packages/svelte/messages/client-errors/errors.md | 2 +- .../svelte/src/compiler/phases/2-analyze/index.js | 2 +- .../phases/3-transform/client/transform-client.js | 4 ++-- .../phases/3-transform/server/transform-server.js | 2 +- packages/svelte/src/compiler/types/index.d.ts | 10 +++++----- packages/svelte/src/compiler/validate-options.js | 8 ++++++-- .../svelte/src/internal/client/dom/legacy/misc.js | 4 ++-- packages/svelte/src/internal/client/errors.js | 4 ++-- .../binding-this-legacy-component-api/_config.js | 4 ++-- .../samples/legacy-class-transformation/_config.js | 4 ++-- packages/svelte/types/index.d.ts | 12 ++++++------ .../docs/content/03-appendix/02-breaking-changes.md | 6 ++++-- sites/svelte-5-preview/svelte.config.js | 4 ++-- 14 files changed, 41 insertions(+), 30 deletions(-) create mode 100644 .changeset/sour-tomatoes-knock.md diff --git a/.changeset/sour-tomatoes-knock.md b/.changeset/sour-tomatoes-knock.md new file mode 100644 index 0000000000..069b7d3f88 --- /dev/null +++ b/.changeset/sour-tomatoes-knock.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +breaking: rename `legacy.componentApi` to `compatibility.componentApi` diff --git a/packages/svelte/messages/client-errors/errors.md b/packages/svelte/messages/client-errors/errors.md index 3e64b90899..e51242d8f6 100644 --- a/packages/svelte/messages/client-errors/errors.md +++ b/packages/svelte/messages/client-errors/errors.md @@ -16,7 +16,7 @@ ## component_api_invalid_new -> Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `legacy.componentApi` compiler option to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information +> Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information ## each_key_duplicate diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index aab31869cd..5a44c30d17 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -383,7 +383,7 @@ export function analyze_component(root, source, options) { ? true : (runes ? false : !!options.accessors) || // because $set method needs accessors - !!options.legacy?.componentApi, + options.compatibility?.componentApi === 4, reactive_statements: new Map(), binding_groups: new Map(), slot_names: new Map(), diff --git a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js index a8438c0aca..d8ceb45372 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/transform-client.js @@ -283,7 +283,7 @@ export function client_component(source, analysis, options) { } } - if (options.legacy.componentApi) { + if (options.compatibility.componentApi === 4) { component_returned_object.push( b.init('$set', b.id('$.update_legacy_props')), b.init( @@ -474,7 +474,7 @@ export function client_component(source, analysis, options) { body.unshift(b.imports([], 'svelte/internal/disclose-version')); } - if (options.legacy.componentApi) { + if (options.compatibility.componentApi === 4) { body.unshift(b.imports([['createClassComponent', '$$_createClassComponent']], 'svelte/legacy')); component_block.body.unshift( b.if( 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 9359f967df..969a88418e 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 @@ -2172,7 +2172,7 @@ export function server_component(analysis, options) { should_inject_props ? [b.id('$$payload'), b.id('$$props')] : [b.id('$$payload')], component_block ); - if (options.legacy.componentApi) { + if (options.compatibility.componentApi === 4) { body.unshift(b.imports([['render', '$$_render']], 'svelte/server')); body.push( component_function, diff --git a/packages/svelte/src/compiler/types/index.d.ts b/packages/svelte/src/compiler/types/index.d.ts index 9574491756..dfcd6467a3 100644 --- a/packages/svelte/src/compiler/types/index.d.ts +++ b/packages/svelte/src/compiler/types/index.d.ts @@ -141,14 +141,14 @@ export interface CompileOptions extends ModuleCompileOptions { /** * @deprecated Use these only as a temporary solution before migrating your code */ - legacy?: { + compatibility?: { /** * Applies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 — * as a class when compiling for the browser (as though using `createClassComponent(MyComponent, {...})` from `svelte/legacy`) * or as an object with a `.render(...)` method when compiling for the server - * @default false + * @default 5 */ - componentApi?: boolean; + componentApi?: 4 | 5; }; /** * An initial sourcemap that will be merged into the final output sourcemap. @@ -226,7 +226,7 @@ export type ValidatedCompileOptions = ValidatedModuleCompileOptions & Required<CompileOptions>, | keyof ModuleCompileOptions | 'name' - | 'legacy' + | 'compatibility' | 'outputFilename' | 'cssOutputFilename' | 'sourcemap' @@ -236,7 +236,7 @@ export type ValidatedCompileOptions = ValidatedModuleCompileOptions & outputFilename: CompileOptions['outputFilename']; cssOutputFilename: CompileOptions['cssOutputFilename']; sourcemap: CompileOptions['sourcemap']; - legacy: Required<Required<CompileOptions>['legacy']>; + compatibility: Required<Required<CompileOptions>['compatibility']>; runes: CompileOptions['runes']; customElementOptions: SvelteOptions['customElement']; hmr: CompileOptions['hmr']; diff --git a/packages/svelte/src/compiler/validate-options.js b/packages/svelte/src/compiler/validate-options.js index bd997a36ab..b90f9427b1 100644 --- a/packages/svelte/src/compiler/validate-options.js +++ b/packages/svelte/src/compiler/validate-options.js @@ -78,8 +78,12 @@ export const validate_component_options = immutable: deprecate(w.options_deprecated_immutable, boolean(false)), - legacy: object({ - componentApi: boolean(false) + legacy: removed( + 'The legacy option has been removed. If you are using this because of legacy.componentApi, use compatibility.componentApi instead' + ), + + compatibility: object({ + componentApi: list([4, 5], 5) }), loopGuardTimeout: warn_removed(w.options_removed_loop_guard_timeout), diff --git a/packages/svelte/src/internal/client/dom/legacy/misc.js b/packages/svelte/src/internal/client/dom/legacy/misc.js index b9ef9fc53a..6048b45d30 100644 --- a/packages/svelte/src/internal/client/dom/legacy/misc.js +++ b/packages/svelte/src/internal/client/dom/legacy/misc.js @@ -41,7 +41,7 @@ export function bubble_event($$props, event) { } /** - * Used to simulate `$on` on a component instance when `legacy.componentApi` is `true` + * Used to simulate `$on` on a component instance when `compatibility.componentApi === 4` * @param {Record<string, any>} $$props * @param {string} event_name * @param {Function} event_callback @@ -53,7 +53,7 @@ export function add_legacy_event_listener($$props, event_name, event_callback) { } /** - * Used to simulate `$set` on a component instance when `legacy.componentApi` is `true`. + * Used to simulate `$set` on a component instance when `compatibility.componentApi === 4`. * Needs component accessors so that it can call the setter of the prop. Therefore doesn't * work for updating props in `$$props` or `$$restProps`. * @this {Record<string, any>} diff --git a/packages/svelte/src/internal/client/errors.js b/packages/svelte/src/internal/client/errors.js index ba41a560c3..f7ab6597af 100644 --- a/packages/svelte/src/internal/client/errors.js +++ b/packages/svelte/src/internal/client/errors.js @@ -76,14 +76,14 @@ export function component_api_changed(parent, method, component) { } /** - * Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `legacy.componentApi` compiler option to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information + * Attempted to instantiate %component% with `new %name%`, which is no longer valid in Svelte 5. If this component is not under your control, set the `compatibility.componentApi` compiler option to `4` to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information * @param {string} component * @param {string} name * @returns {never} */ export function component_api_invalid_new(component, name) { if (DEV) { - const error = new Error(`component_api_invalid_new\nAttempted to instantiate ${component} with \`new ${name}\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \`legacy.componentApi\` compiler option to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`); + const error = new Error(`component_api_invalid_new\nAttempted to instantiate ${component} with \`new ${name}\`, which is no longer valid in Svelte 5. If this component is not under your control, set the \`compatibility.componentApi\` compiler option to \`4\` to keep it working. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information`); error.name = 'Svelte error'; throw error; diff --git a/packages/svelte/tests/runtime-legacy/samples/binding-this-legacy-component-api/_config.js b/packages/svelte/tests/runtime-legacy/samples/binding-this-legacy-component-api/_config.js index a4ab247250..c3ba255930 100644 --- a/packages/svelte/tests/runtime-legacy/samples/binding-this-legacy-component-api/_config.js +++ b/packages/svelte/tests/runtime-legacy/samples/binding-this-legacy-component-api/_config.js @@ -3,8 +3,8 @@ import { test } from '../../test'; export default test({ compileOptions: { - legacy: { - componentApi: true + compatibility: { + componentApi: 4 } }, html: '<button>0</button>', diff --git a/packages/svelte/tests/runtime-runes/samples/legacy-class-transformation/_config.js b/packages/svelte/tests/runtime-runes/samples/legacy-class-transformation/_config.js index e271e4f9b2..95c57cc255 100644 --- a/packages/svelte/tests/runtime-runes/samples/legacy-class-transformation/_config.js +++ b/packages/svelte/tests/runtime-runes/samples/legacy-class-transformation/_config.js @@ -2,8 +2,8 @@ import { test } from '../../test'; export default test({ compileOptions: { - legacy: { - componentApi: true + compatibility: { + componentApi: 4 } }, diff --git a/packages/svelte/types/index.d.ts b/packages/svelte/types/index.d.ts index 5055799a9d..85349af2c4 100644 --- a/packages/svelte/types/index.d.ts +++ b/packages/svelte/types/index.d.ts @@ -802,14 +802,14 @@ declare module 'svelte/compiler' { /** * @deprecated Use these only as a temporary solution before migrating your code */ - legacy?: { + compatibility?: { /** * Applies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 — * as a class when compiling for the browser (as though using `createClassComponent(MyComponent, {...})` from `svelte/legacy`) * or as an object with a `.render(...)` method when compiling for the server - * @default false + * @default 5 */ - componentApi?: boolean; + componentApi?: 4 | 5; }; /** * An initial sourcemap that will be merged into the final output sourcemap. @@ -2610,14 +2610,14 @@ declare module 'svelte/types/compiler/interfaces' { /** * @deprecated Use these only as a temporary solution before migrating your code */ - legacy?: { + compatibility?: { /** * Applies a transformation so that the default export of Svelte files can still be instantiated the same way as in Svelte 4 — * as a class when compiling for the browser (as though using `createClassComponent(MyComponent, {...})` from `svelte/legacy`) * or as an object with a `.render(...)` method when compiling for the server - * @default false + * @default 5 */ - componentApi?: boolean; + componentApi?: 4 | 5; }; /** * An initial sourcemap that will be merged into the final output sourcemap. diff --git a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md index 8de2bfbfe4..65300276ea 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md @@ -70,13 +70,15 @@ import App from './App.svelte' export default app; ``` -If this component is not under your control, you can use the `legacy.componentApi` compiler option for auto-applied backwards compatibility, which means code using `new Component(...)` keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add `$set` and `$on` methods for all component instances you get through `bind:this`. +If this component is not under your control, you can use the `compatibility.componentApi` compiler option for auto-applied backwards compatibility, which means code using `new Component(...)` keeps working without adjustments (note that this adds a bit of overhead to each component). This will also add `$set` and `$on` methods for all component instances you get through `bind:this`. ```js /// svelte.config.js export default { compilerOptions: { - legacy: { componentApi: true } + compatibility: { + componentApi: 4 + } } }; ``` diff --git a/sites/svelte-5-preview/svelte.config.js b/sites/svelte-5-preview/svelte.config.js index de3e5cfa05..d2d2d8019d 100644 --- a/sites/svelte-5-preview/svelte.config.js +++ b/sites/svelte-5-preview/svelte.config.js @@ -3,9 +3,9 @@ import adapter from '@sveltejs/adapter-vercel'; /** @type {import('@sveltejs/kit').Config} */ export default { compilerOptions: { - legacy: { + compatibility: { // site-kit manually instantiates components inside an action - componentApi: true + componentApi: 4 } }, kit: {