From b49c510e2975e8b5e0cedea23b8c71c441a5176a Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 10 Oct 2024 16:39:13 +0200 Subject: [PATCH 01/13] docs: wire up compiler/runtime warnigns/errors --- .../svelte/98-reference/30-compiler-errors.md | 949 ++++++++++++++++++ .../98-reference/30-compiler-warnings.md | 523 ++++++++++ .../svelte/98-reference/30-runtime-errors.md | 163 +++ .../98-reference/30-runtime-warnings.md | 115 +++ apps/svelte.dev/src/hooks.server.js | 3 +- apps/svelte.dev/src/routes/docs/+page.svelte | 2 +- 6 files changed, 1753 insertions(+), 2 deletions(-) create mode 100644 apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md create mode 100644 apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-warnings.md create mode 100644 apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-errors.md create mode 100644 apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-warnings.md diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md new file mode 100644 index 0000000000..ebcaa28ef8 --- /dev/null +++ b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md @@ -0,0 +1,949 @@ +--- +title: 'Compiler Errors' +generated: 'generated by process-messages/index.js' +--- + +## options_invalid_value + +``` +Invalid compiler option: %details% +``` + +## options_removed + +``` +Invalid compiler option: %details% +``` + +## options_unrecognised + +``` +Unrecognised compiler option %keypath% +``` + +## bindable_invalid_location + +``` +`$bindable()` can only be used inside a `$props()` declaration +``` + +## constant_assignment + +``` +Cannot assign to %thing% +``` + +## constant_binding + +``` +Cannot bind to %thing% +``` + +## declaration_duplicate + +``` +`%name%` has already been declared +``` + +## declaration_duplicate_module_import + +``` +Cannot declare a variable with the same name as an import inside ` +- ++ +``` + +## svelte_element_invalid_this + +``` +`this` should be an `{expression}`. Using a string attribute value will cause an error in future versions of Svelte +``` + +## svelte_self_deprecated + +``` +`` is deprecated — use self-imports (e.g. `import %name% from './%basename%'`) instead +``` diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-errors.md new file mode 100644 index 0000000000..8c7b286a7b --- /dev/null +++ b/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-errors.md @@ -0,0 +1,163 @@ +--- +title: 'Runtime Errors' +generated: 'generated by process-messages/index.js' +--- + +## bind_invalid_checkbox_value + +``` +Using `bind:value` together with a checkbox input is not allowed. Use `bind:checked` instead +``` + +## bind_invalid_export + +``` +Component %component% has an export named `%key%` that a consumer component is trying to access using `bind:%key%`, which is disallowed. Instead, use `bind:this` (e.g. `<%name% bind:this={component} />`) and then access the property on the bound component instance (e.g. `component.%key%`) +``` + +## bind_not_bindable + +``` +A component is attempting to bind to a non-bindable property `%key%` belonging to %component% (i.e. `<%name% bind:%key%={...}>`). To mark a property as bindable: `let { %key% = $bindable() } = $props()` +``` + +## component_api_changed + +``` +%parent% called `%method%` on an instance of %component%, which is no longer valid in Svelte 5. See https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes for more information +``` + +## 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 `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 +``` + +## derived_references_self + +``` +A derived value cannot reference itself recursively +``` + +## each_key_duplicate + +``` +Keyed each block has duplicate key at indexes %a% and %b% +``` +``` +Keyed each block has duplicate key `%value%` at indexes %a% and %b% +``` + +## effect_in_teardown + +``` +`%rune%` cannot be used inside an effect cleanup function +``` + +## effect_in_unowned_derived + +``` +Effect cannot be created inside a `$derived` value that was not itself created inside an effect +``` + +## effect_orphan + +``` +`%rune%` can only be used inside an effect (e.g. during component initialisation) +``` + +## effect_update_depth_exceeded + +``` +Maximum update depth exceeded. This can happen when a reactive block or effect repeatedly sets a new value. Svelte limits the number of nested updates to prevent infinite loops +``` + +## hydration_failed + +``` +Failed to hydrate the application +``` + +## invalid_snippet + +``` +Could not `{@render}` snippet due to the expression being `null` or `undefined`. Consider using optional chaining `{@render snippet?.()}` +``` + +## lifecycle_legacy_only + +``` +`%name%(...)` cannot be used in runes mode +``` + +## props_invalid_value + +``` +Cannot do `bind:%key%={undefined}` when `%key%` has a fallback value +``` + +## props_rest_readonly + +``` +Rest element properties of `$props()` such as `%property%` are readonly +``` + +## rune_outside_svelte + +``` +The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files +``` + +## state_descriptors_fixed + +``` +Property descriptors defined on `$state` objects must contain `value` and always be `enumerable`, `configurable` and `writable`. +``` + +## state_prototype_fixed + +``` +Cannot set prototype of `$state` object +``` + +## state_unsafe_local_read + +``` +Reading state that was created inside the same derived is forbidden. Consider using `untrack` to read locally created state +``` + +## state_unsafe_mutation + +``` +Updating state inside a derived is forbidden. If the value should not be reactive, declare it without `$state` +``` + +## lifecycle_function_unavailable + +``` +`%name%(...)` is not available on the server +``` + +## invalid_default_snippet + +``` +Cannot use `{@render children(...)}` if the parent component uses `let:` directives. Consider using a named snippet instead +``` + +## lifecycle_outside_component + +``` +`%name%(...)` can only be used during component initialisation +``` + +## store_invalid_shape + +``` +`%name%` is not a store with a `subscribe` method +``` + +## svelte_element_invalid_this_value + +``` +The `this` prop on `` must be a string, if defined +``` diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-warnings.md b/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-warnings.md new file mode 100644 index 0000000000..c1c6ba2fb1 --- /dev/null +++ b/apps/svelte.dev/content/docs/svelte/98-reference/30-runtime-warnings.md @@ -0,0 +1,115 @@ +--- +title: 'Runtime Warnings' +generated: 'generated by process-messages/index.js' +--- + +## binding_property_non_reactive + +``` +`%binding%` is binding to a non-reactive property +``` +``` +`%binding%` (%location%) is binding to a non-reactive property +``` + +## console_log_state + +``` +Your `console.%method%` contained `$state` proxies. Consider using `$inspect(...)` or `$state.snapshot(...)` instead +``` + +When logging a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy), browser devtools will log the proxy itself rather than the value it represents. In the case of Svelte, the 'target' of a `$state` proxy might not resemble its current value, which can be confusing. + +The easiest way to log a value as it changes over time is to use the [`$inspect`](https://svelte-5-preview.vercel.app/docs/runes#$inspect) rune. Alternatively, to log things on a one-off basis (for example, inside an event handler) you can use [`$state.snapshot`](https://svelte-5-preview.vercel.app/docs/runes#$state-snapshot) to take a snapshot of the current value. + +## event_handler_invalid + +``` +%handler% should be a function. Did you mean to %suggestion%? +``` + +## hydration_attribute_changed + +``` +The `%attribute%` attribute on `%html%` changed its value between server and client renders. The client value, `%value%`, will be ignored in favour of the server value +``` + +## hydration_html_changed + +``` +The value of an `{@html ...}` block changed between server and client renders. The client value will be ignored in favour of the server value +``` +``` +The value of an `{@html ...}` block %location% changed between server and client renders. The client value will be ignored in favour of the server value +``` + +## hydration_mismatch + +``` +Hydration failed because the initial UI does not match what was rendered on the server +``` +``` +Hydration failed because the initial UI does not match what was rendered on the server. The error occurred near %location% +``` + +## invalid_raw_snippet_render + +``` +The `render` function passed to `createRawSnippet` should return HTML for a single element +``` + +## lifecycle_double_unmount + +``` +Tried to unmount a component that was not mounted +``` + +## ownership_invalid_binding + +``` +%parent% passed a value to %child% with `bind:`, but the value is owned by %owner%. Consider creating a binding between %owner% and %parent% +``` + +## ownership_invalid_mutation + +``` +Mutating a value outside the component that created it is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead +``` +``` +%component% mutated a value owned by %owner%. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead +``` + +## state_proxy_equality_mismatch + +``` +Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `%operator%` will produce unexpected results +``` + +`$state(...)` creates a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) of the value it is passed. The proxy and the value have different identities, meaning equality checks will always return `false`: + +```svelte + +``` + +To resolve this, ensure you're comparing values where both values were created with `$state(...)`, or neither were. Note that `$state.raw(...)` will _not_ create a state proxy. + +## dynamic_void_element_content + +``` +`` is a void element — it cannot have content +``` + +## state_snapshot_uncloneable + +``` +Value cannot be cloned with `$state.snapshot` — the original value was returned +``` +``` +The following properties cannot be cloned with `$state.snapshot` — the return value contains the originals: +%properties% +``` diff --git a/apps/svelte.dev/src/hooks.server.js b/apps/svelte.dev/src/hooks.server.js index 6b194ed65e..0f78962d93 100644 --- a/apps/svelte.dev/src/hooks.server.js +++ b/apps/svelte.dev/src/hooks.server.js @@ -6,7 +6,8 @@ const mappings = new Map([ ['/docs/special-tags', '/docs/svelte/basic-markup'], // TODO: find a new home for some of these? ['/docs/element-directives', '/docs/svelte/basic-markup'], ['/docs/component-directives', '/docs/svelte/component-fundamentals'], - ['/docs/custom-elements-api', '/docs/svelte/custom-elements'] + ['/docs/custom-elements-api', '/docs/svelte/custom-elements'], + ['/docs/accessibility-warnings', '/docs/svelte/compiler-warnings'] ]); /** @type {import('@sveltejs/kit').Handle} */ diff --git a/apps/svelte.dev/src/routes/docs/+page.svelte b/apps/svelte.dev/src/routes/docs/+page.svelte index 6f00a685e0..fe860f0ed5 100644 --- a/apps/svelte.dev/src/routes/docs/+page.svelte +++ b/apps/svelte.dev/src/routes/docs/+page.svelte @@ -35,7 +35,7 @@ ['run-time-svelte', 'svelte'], ['run-time', 'svelte'], ['compile-time', 'svelte-compiler'], - ['accessibility-warnings', 'TODO'] + ['accessibility-warnings', 'compiler-warnings'] ]; function get_url_to_redirect_to() { From 1501e5bc805d5b646cb8e4c5ed778f98ee07d8b0 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 10 Oct 2024 16:48:35 +0200 Subject: [PATCH 02/13] allow (and properly style) code blocks in headings --- apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte | 1 + packages/site-kit/src/lib/markdown/renderer.ts | 5 +---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte b/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte index c90495b60e..4e6df3af8c 100644 --- a/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte +++ b/apps/svelte.dev/src/routes/docs/[...path]/+layout.svelte @@ -31,6 +31,7 @@ .page :global(:where(h2, h3) code) { all: unset; + font-family: var(--sk-font-mono); } @media (min-width: 832px) { diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index 694d258d19..73bed8fea7 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -269,10 +269,7 @@ export async function render_content_markdown( headings[depth - 1] = slugify(raw); headings.length = depth; const slug = headings.filter(Boolean).join('-'); - return `${text.replace( - /<\/?code>/g, - '' - )}`; + return `${text}`; }, code({ text }) { return snippets.get(text); From 4812715bd0f2a90120250811cd611a794f76c004 Mon Sep 17 00:00:00 2001 From: Simon Holthausen Date: Thu, 10 Oct 2024 16:55:30 +0200 Subject: [PATCH 03/13] testbed --- .../docs/svelte/98-reference/30-compiler-errors.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md index ebcaa28ef8..0e602e4836 100644 --- a/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md +++ b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md @@ -1,13 +1,11 @@ --- -title: 'Compiler Errors' +title: 'Compiler errors' generated: 'generated by process-messages/index.js' --- -## options_invalid_value +## `options_invalid_value` -``` -Invalid compiler option: %details% -``` +> Invalid compiler option: %details% ## options_removed @@ -436,6 +434,7 @@ Can only bind to an Identifier or MemberExpression ``` `bind:%name%` is not a valid binding ``` + ``` `bind:%name%` is not a valid binding. %explanation% ``` From cd17a13ba9002ce9edddc82a0cd6d313cdfd5e44 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 10 Oct 2024 12:49:40 -0400 Subject: [PATCH 04/13] wire up correct branch --- .../svelte/98-reference/30-compiler-errors.md | 579 +++++++++--------- .../98-reference/30-compiler-warnings.md | 254 ++++---- .../svelte/98-reference/30-runtime-errors.md | 78 +-- .../98-reference/30-runtime-warnings.md | 38 +- apps/svelte.dev/scripts/sync-docs/index.ts | 2 +- 5 files changed, 476 insertions(+), 475 deletions(-) diff --git a/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md index 0e602e4836..14c2c05799 100644 --- a/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md +++ b/apps/svelte.dev/content/docs/svelte/98-reference/30-compiler-errors.md @@ -3,863 +3,858 @@ title: 'Compiler errors' generated: 'generated by process-messages/index.js' --- -## `options_invalid_value` - -> Invalid compiler option: %details% - -## options_removed +## `animation_duplicate` ``` -Invalid compiler option: %details% +An element can only have one 'animate' directive ``` -## options_unrecognised +## `animation_invalid_placement` ``` -Unrecognised compiler option %keypath% +An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block ``` -## bindable_invalid_location +## `animation_missing_key` ``` -`$bindable()` can only be used inside a `$props()` declaration +An element that uses the `animate:` directive must be the only child of a keyed `{#each ...}` block. Did you forget to add a key to your each block? ``` -## constant_assignment +## `attribute_contenteditable_dynamic` ``` -Cannot assign to %thing% +'contenteditable' attribute cannot be dynamic if element uses two-way binding ``` -## constant_binding +## `attribute_contenteditable_missing` ``` -Cannot bind to %thing% +'contenteditable' attribute is required for textContent, innerHTML and innerText two-way bindings ``` -## declaration_duplicate +## `attribute_duplicate` ``` -`%name%` has already been declared +Attributes need to be unique ``` -## declaration_duplicate_module_import +## `attribute_empty_shorthand` ``` -Cannot declare a variable with the same name as an import inside ` ``` -## `tick` +## tick While there's no "after update" hook, you can use `tick` to ensure that the UI is updated before continuing. `tick` returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none. @@ -90,7 +90,7 @@ While there's no "after update" hook, you can use `tick` to ensure that the UI i ``` -## Deprecated: `beforeUpdate` / `afterUpdate` +## Deprecated: beforeUpdate/afterUpdate Svelte 4 contained hooks that ran before and after the component as a whole was updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not available inside components that use runes. diff --git a/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md b/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md index b4517bd34f..1594ae9e2d 100644 --- a/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md +++ b/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md @@ -12,7 +12,7 @@ better title needed? Every Svelte application starts by imperatively creating a root component. On the client this component is mounted to a specific element. On the server, you want to get back a string of HTML instead which you can render. The following functions help you achieve those tasks. -## `mount` +## mount Instantiates a component and mounts it to the given target: @@ -31,7 +31,7 @@ You can mount multiple components per page, and you can also mount from within y Note that unlike calling `new App(...)` in Svelte 4, things like effects (including `onMount` callbacks, and action functions) will not run during `mount`. If you need to force pending effects to run (in the context of a test, for example) you can do so with `flushSync()`. -## `unmount` +## unmount Unmounts a component created with [`mount`](#mount) or [`hydrate`](#hydrate): @@ -46,7 +46,7 @@ const app = mount(App, {...}); unmount(app); ``` -## `render` +## render Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app: @@ -62,7 +62,7 @@ result.body; // HTML for somewhere in this tag result.head; // HTML for somewhere in this tag ``` -## `hydrate` +## hydrate Like `mount`, but will reuse up any HTML rendered by Svelte's SSR output (from the [`render`](#server-render) function) inside the target and make it interactive: diff --git a/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md b/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md index f07baa13fd..428cd066af 100644 --- a/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md +++ b/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md @@ -7,7 +7,7 @@ title: Debugging Svelte provides two built-in ways to debug your application. -## `$inspect` +## $inspect The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object diff --git a/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md b/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md index 10f0dd30eb..1d95c36984 100644 --- a/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md +++ b/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md @@ -10,7 +10,7 @@ title: TypeScript You can use TypeScript within Svelte components. IDE extensions like the [Svelte VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) will help you catch errors right in your editor, and [`svelte-check`](https://www.npmjs.com/package/svelte-check) does the same on the command line, which you can integrate into your CI. -## ` ``` -## tick +## `tick` While there's no "after update" hook, you can use `tick` to ensure that the UI is updated before continuing. `tick` returns a promise that resolves once any pending state changes have been applied, or in the next microtask if there are none. @@ -90,7 +90,7 @@ While there's no "after update" hook, you can use `tick` to ensure that the UI i ``` -## Deprecated: beforeUpdate/afterUpdate +## Deprecated: `beforeUpdate` / `afterUpdate` Svelte 4 contained hooks that ran before and after the component as a whole was updated. For backwards compatibility, these hooks were shimmed in Svelte 5 but not available inside components that use runes. diff --git a/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md b/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md index 1594ae9e2d..b4517bd34f 100644 --- a/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md +++ b/apps/svelte.dev/content/docs/svelte/04-runtime/04-imperative-component-api.md @@ -12,7 +12,7 @@ better title needed? Every Svelte application starts by imperatively creating a root component. On the client this component is mounted to a specific element. On the server, you want to get back a string of HTML instead which you can render. The following functions help you achieve those tasks. -## mount +## `mount` Instantiates a component and mounts it to the given target: @@ -31,7 +31,7 @@ You can mount multiple components per page, and you can also mount from within y Note that unlike calling `new App(...)` in Svelte 4, things like effects (including `onMount` callbacks, and action functions) will not run during `mount`. If you need to force pending effects to run (in the context of a test, for example) you can do so with `flushSync()`. -## unmount +## `unmount` Unmounts a component created with [`mount`](#mount) or [`hydrate`](#hydrate): @@ -46,7 +46,7 @@ const app = mount(App, {...}); unmount(app); ``` -## render +## `render` Only available on the server and when compiling with the `server` option. Takes a component and returns an object with `body` and `head` properties on it, which you can use to populate the HTML when server-rendering your app: @@ -62,7 +62,7 @@ result.body; // HTML for somewhere in this tag result.head; // HTML for somewhere in this tag ``` -## hydrate +## `hydrate` Like `mount`, but will reuse up any HTML rendered by Svelte's SSR output (from the [`render`](#server-render) function) inside the target and make it interactive: diff --git a/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md b/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md index 428cd066af..f07baa13fd 100644 --- a/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md +++ b/apps/svelte.dev/content/docs/svelte/05-misc/01-debugging.md @@ -7,7 +7,7 @@ title: Debugging Svelte provides two built-in ways to debug your application. -## $inspect +## `$inspect` The `$inspect` rune is roughly equivalent to `console.log`, with the exception that it will re-run whenever its argument changes. `$inspect` tracks reactive state deeply, meaning that updating something inside an object diff --git a/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md b/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md index 1d95c36984..10f0dd30eb 100644 --- a/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md +++ b/apps/svelte.dev/content/docs/svelte/05-misc/03-typescript.md @@ -10,7 +10,7 @@ title: TypeScript You can use TypeScript within Svelte components. IDE extensions like the [Svelte VS Code extension](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode) will help you catch errors right in your editor, and [`svelte-check`](https://www.npmjs.com/package/svelte-check) does the same on the command line, which you can integrate into your CI. -##