Skip to main content

Svelte 4 迁移指南

本迁移指南概述了如何从 Svelte 版本 3 迁移到 4。请参阅链接的 PR 了解有关每个更改的更多详细信息。使用迁移脚本自动迁移其中一些内容:npx svelte-migrate@latest svelte-4

¥This migration guide provides an overview of how to migrate from Svelte version 3 to 4. See the linked PRs for more details about each change. Use the migration script to migrate some of these automatically: npx svelte-migrate@latest svelte-4

如果你是库作者,请考虑是否仅支持 Svelte 4 或是否也可以支持 Svelte 3。由于大多数重大更改不会影响很多人,因此这可能很容易实现。还要记得更新 peerDependencies 中的版本范围。

¥If you’re a library author, consider whether to only support Svelte 4 or if it’s possible to support Svelte 3 too. Since most of the breaking changes don’t affect many people, this may be easily possible. Also remember to update the version range in your peerDependencies.

最低版本要求(Minimum version requirements)

¥Minimum version requirements

  • 升级到 Node 16 或更高版本。不再支持早期版本。(#8566)

    ¥Upgrade to Node 16 or higher. Earlier versions are no longer supported. (#8566)

  • 如果你使用的是 SvelteKit,请升级到 1.20.4 或更新版本 (sveltejs/kit#10172)

    ¥If you are using SvelteKit, upgrade to 1.20.4 or newer (sveltejs/kit#10172)

  • 如果你使用的是没有 SvelteKit 的 Vite,请升级到 vite-plugin-svelte 2.4.1 或更新版本 (#8516)

    ¥If you are using Vite without SvelteKit, upgrade to vite-plugin-svelte 2.4.1 or newer (#8516)

  • 如果你使用的是 webpack,请升级到 webpack 5 或更高版本和 svelte-loader 3.1.8 或更高版本。不再支持早期版本。(#8515, 198dbcf)

    ¥If you are using webpack, upgrade to webpack 5 or higher and svelte-loader 3.1.8 or higher. Earlier versions are no longer supported. (#8515, 198dbcf)

  • 如果你使用的是 Rollup,请升级到 rollup-plugin-svelte 7.1.5 或更高版本 (198dbcf)

    ¥If you are using Rollup, upgrade to rollup-plugin-svelte 7.1.5 or higher (198dbcf)

  • 如果你使用的是 TypeScript,请升级到 TypeScript 5 或更高版本。较低版本可能仍可行,但不保证一定有效。(#8488)

    ¥If you are using TypeScript, upgrade to TypeScript 5 or higher. Lower versions might still work, but no guarantees are made about that. (#8488)

打包器的浏览器条件(Browser conditions for bundlers)

¥Browser conditions for bundlers

打包器现在必须在为浏览器构建前端打包包时指定 browser 条件。SvelteKit 和 Vite 会自动为你处理此问题。如果你使用的是其他任何版本,你可能会发现生命周期回调(例如 onMount)未被调用,你需要更新模块解析配置。

¥Bundlers must now specify the browser condition when building a frontend bundle for the browser. SvelteKit and Vite will handle this automatically for you. If you’re using any others, you may observe lifecycle callbacks such as onMount not get called and you’ll need to update the module resolution configuration.

  • 对于 Rollup,这是在 @rollup/plugin-node-resolve 插件中通过在其选项中设置 browser: true 来完成的。有关更多详细信息,请参阅 rollup-plugin-svelte 文档

    ¥For Rollup this is done within the @rollup/plugin-node-resolve plugin by setting browser: true in its options. See the rollup-plugin-svelte documentation for more details

  • 对于 webpack,这是通过将 "browser" 添加到 conditionNames 数组来完成的。如果你已设置,你可能还必须更新 alias 配置。有关更多详细信息,请参阅 svelte-loader 文档

    ¥For webpack this is done by adding "browser" to the conditionNames array. You may also have to update your alias config, if you have set it. See the svelte-loader documentation for more details

(#8516)

¥Removal of CJS related output

Svelte 不再支持 CommonJS (CJS) 编译器输出格式,并且还删除了 svelte/register 钩子和 CJS 运行时版本。如果你需要保留 CJS 输出格式,请考虑使用打包器在构建后步骤中将 Svelte 的 ESM 输出转换为 CJS。(#8613)

¥Svelte no longer supports the CommonJS (CJS) format for compiler output and has also removed the svelte/register hook and the CJS runtime version. If you need to stay on the CJS output format, consider using a bundler to convert Svelte’s ESM output to CJS in a post-build step. (#8613)

Svelte 函数的更严格类型(Stricter types for Svelte functions)

¥Stricter types for Svelte functions

现在 createEventDispatcherActionActionReturnonMount 有更严格的类型:

¥There are now stricter types for createEventDispatcher, Action, ActionReturn, and onMount:

  • createEventDispatcher 现在支持指定有效负载是可选的、必需的还是不存在的,并相应地检查调用站点(#7224

    ¥createEventDispatcher now supports specifying that a payload is optional, required, or non-existent, and the call sites are checked accordingly (#7224)

import { function createEventDispatcher<EventMap extends Record<string, any> = any>(): EventDispatcher<EventMap>

Creates an event dispatcher that can be used to dispatch component events. Event dispatchers are functions that can take two arguments: name and detail.

Component events created with createEventDispatcher create a CustomEvent. These events do not bubble. The detail argument corresponds to the CustomEvent.detail property and can contain any type of data.

The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:

const dispatch = createEventDispatcher&#x3C;{
 loaded: never; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();
@deprecatedUse callback props and/or the $host() rune instead — see migration guide
createEventDispatcher
} from 'svelte';
const
const dispatch: EventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}>
dispatch
=
createEventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}>(): EventDispatcher<{
    optional: number | null;
    required: string;
    noArgument: null;
}>

Creates an event dispatcher that can be used to dispatch component events. Event dispatchers are functions that can take two arguments: name and detail.

Component events created with createEventDispatcher create a CustomEvent. These events do not bubble. The detail argument corresponds to the CustomEvent.detail property and can contain any type of data.

The event dispatcher can be typed to narrow the allowed event names and the type of the detail argument:

const dispatch = createEventDispatcher&#x3C;{
 loaded: never; // does not take a detail argument
 change: string; // takes a detail argument of type string, which is required
 optional: number | null; // takes an optional detail argument of type number
}>();
@deprecatedUse callback props and/or the $host() rune instead — see migration guide
createEventDispatcher
<{
optional: number | nulloptional: number | null; required: stringrequired: string; noArgument: nullnoArgument: null; }>(); // Svelte version 3:
const dispatch: EventDispatcher
<"optional">(type: "optional", parameter?: number | null | undefined, options?: DispatchOptions | undefined) => boolean
dispatch
('optional');
const dispatch: EventDispatcher
<"required">(type: "required", parameter: string, options?: DispatchOptions | undefined) => boolean
dispatch
('required'); // I can still omit the detail argument
const dispatch: EventDispatcher
<"noArgument">(type: "noArgument", parameter?: null | undefined, options?: DispatchOptions | undefined) => boolean
dispatch
('noArgument', 'surprise'); // I can still add a detail argument
// Svelte version 4 using TypeScript strict mode:
const dispatch: EventDispatcher
<"optional">(type: "optional", parameter?: number | null | undefined, options?: DispatchOptions | undefined) => boolean
dispatch
('optional');
const dispatch: EventDispatcher
<"required">(type: "required", parameter: string, options?: DispatchOptions | undefined) => boolean
dispatch
('required'); // error, missing argument
const dispatch: EventDispatcher
<"noArgument">(type: "noArgument", parameter?: null | undefined, options?: DispatchOptions | undefined) => boolean
dispatch
('noArgument', 'surprise'); // error, cannot pass an argument
  • ActionActionReturn 现在具有默认参数类型 undefined,这意味着如果你想指定此操作接收参数,则需要键入通用参数。迁移脚本将自动迁移此 (#7442)

    ¥Action and ActionReturn have a default parameter type of undefined now, which means you need to type the generic if you want to specify that this action receives a parameter. The migration script will migrate this automatically (#7442)

const action: Action = (node, params) => { ... } // this is now an error if you use params in any way
const const action: Action<HTMLElement, string>action: type Action = /*unresolved*/ anyAction<HTMLElement, string> = (node: anynode, params: anyparams) => { ... } // params is of type string
  • 如果你从 onMount 异步返回一个函数,它现在会显示类型错误,因为这可能是你代码中的一个错误,你希望在销毁时调用回调,而这只会对同步返回的函数执行(#8136

    ¥onMount now shows a type error if you return a function asynchronously from it, because this is likely a bug in your code where you expect the callback to be called on destroy, which it will only do for synchronously returned functions (#8136)

// Example where this change reveals an actual bug
onMount(
	// someCleanup() not called because function handed to onMount is async
	async () => {
		const something = await foo();
           	// someCleanup() is called because function handed to onMount is sync
	() => {
		foo().then(something: anysomething => {...});
		// ...
		return () => someCleanup();
	}
);

使用 Svelte 的自定义元素(Custom Elements with Svelte)

¥Custom Elements with Svelte

使用 Svelte 创建自定义元素已得到彻底改造和显著改进。tag 选项已弃用,取而代之的是新的 customElement 选项:

¥The creation of custom elements with Svelte has been overhauled and significantly improved. The tag option is deprecated in favor of the new customElement option:

<svelte:options tag="my-component" />
<svelte:options customElement="my-component" />

进行此更改是为了允许 更多可配置性 用于高级用例。迁移脚本将自动调整你的代码。属性的更新时间也略有变化。(#8457)

¥This change was made to allow more configurability for advanced use cases. The migration script will adjust your code automatically. The update timing of properties has changed slightly as well. (#8457)

SvelteComponentTyped 已弃用(SvelteComponentTyped is deprecated)

¥SvelteComponentTyped is deprecated

SvelteComponentTyped 已弃用,因为 SvelteComponent 现在具有其所有类型功能。将 SvelteComponentTyped 的所有实例替换为 SvelteComponent

¥SvelteComponentTyped is deprecated, as SvelteComponent now has all its typing capabilities. Replace all instances of SvelteComponentTyped with SvelteComponent.

import { SvelteComponentTyped } from 'svelte';
import { class SvelteComponent<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>

This was the base class for Svelte components in Svelte 4. Svelte 5+ components are completely different under the hood. For typing, use Component instead. To instantiate components, use mount instead. See migration guide for more info.

SvelteComponent
} from 'svelte';
export class Foo extends SvelteComponentTyped<{ aProp: string }> {} export class class FooFoo extends class SvelteComponent<Props extends Record<string, any> = Record<string, any>, Events extends Record<string, any> = any, Slots extends Record<string, any> = any>

This was the base class for Svelte components in Svelte 4. Svelte 5+ components are completely different under the hood. For typing, use Component instead. To instantiate components, use mount instead. See migration guide for more info.

SvelteComponent
<{ aProp: stringaProp: string }> {}

如果你之前使用过 SvelteComponent 作为组件实例类型,你现在可能会看到一个有点不透明的类型错误,可以通过将 : typeof SvelteComponent 更改为 : typeof SvelteComponent<any> 来解决。

¥If you have used SvelteComponent as the component instance type previously, you may see a somewhat opaque type error now, which is solved by changing : typeof SvelteComponent to : typeof SvelteComponent<any>.

<script>
	import ComponentA from './ComponentA.svelte';
	import ComponentB from './ComponentB.svelte';
	import { SvelteComponent } from 'svelte';

	let component: typeof SvelteComponent<any>;

	function choseRandomly() {
		component = Math.random() > 0.5 ? ComponentA : ComponentB;
	}
</script>

<button on:click={choseRandomly}>random</button>
<svelte:element this={component} />

迁移脚本将自动为你完成这两项操作。(#8512)

¥The migration script will do both automatically for you. (#8512)

默认情况下,转换是本地的(Transitions are local by default)

¥Transitions are local by default

默认情况下,过渡现在为本地,以防止页面导航混淆。”local” 表示,如果转换位于嵌套控制流块 (each/if/await/key) 内,并且不是直接父块而是其上方的块被创建/销毁,则转换将不会播放。在下面的例子中,slide 介绍动画只会在 successfalse 变为 true 时播放,但当 showfalse 变为 true 时不会播放:

¥Transitions are now local by default to prevent confusion around page navigations. “local” means that a transition will not play if it’s within a nested control flow block (each/if/await/key) and not the direct parent block but a block above it is created/destroyed. In the following example, the slide intro animation will only play when success goes from false to true, but it will not play when show goes from false to true:

{#if show}
	...
	{#if success}
		<p in:slide>Success</p>
	{/each}
{/if}

要使转换全局化,请添加 |global 修饰符 - 然后它们将在创建/销毁上述任何控制流块时播放。迁移脚本将自动为你完成此操作。(#6686)

¥To make transitions global, add the |global modifier - then they will play when any control flow block above is created/destroyed. The migration script will do this automatically for you. (#6686)

默认插槽绑定(Default slot bindings)

¥Default slot bindings

默认插槽绑定不再暴露给命名插槽,反之亦然:

¥Default slot bindings are no longer exposed to named slots and vice versa:

<script>
	import Nested from './Nested.svelte';
</script>

<Nested let:count>
	<p>
		count in default slot - is available: {count}
	</p>
	<p slot="bar">
		count in bar slot - is not available: {count}
	</p>
</Nested>

这使得插槽绑定更加一致,因为当例如默认插槽来自列表而命名插槽不是时,行为是未定义的。(#6049)

¥This makes slot bindings more consistent as the behavior is undefined when for example the default slot is from a list and the named slot is not. (#6049)

预处理器(Preprocessors)

¥Preprocessors

应用预处理器的顺序已更改。现在,预处理器按顺序执行,在一个组内,顺序是标记、脚本、样式。

¥The order in which preprocessors are applied has changed. Now, preprocessors are executed in order, and within one group, the order is markup, script, style.

import { 
function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
    filename?: string;
} | undefined): Promise<Processed>

The preprocess function provides convenient hooks for arbitrarily transforming component source code. For example, it can be used to convert a &#x3C;style lang="sass"> block into vanilla CSS.

preprocess
} from 'svelte/compiler';
const { const code: string

The new code

code
} = await
function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
    filename?: string;
} | undefined): Promise<Processed>

The preprocess function provides convenient hooks for arbitrarily transforming component source code. For example, it can be used to convert a &#x3C;style lang="sass"> block into vanilla CSS.

preprocess
(
source, [ { PreprocessorGroup.markup?: MarkupPreprocessor | undefinedmarkup: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('markup-1');
}, PreprocessorGroup.script?: Preprocessor | undefinedscript: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('script-1');
}, PreprocessorGroup.style?: Preprocessor | undefinedstyle: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('style-1');
} }, { PreprocessorGroup.markup?: MarkupPreprocessor | undefinedmarkup: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('markup-2');
}, PreprocessorGroup.script?: Preprocessor | undefinedscript: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('script-2');
}, PreprocessorGroup.style?: Preprocessor | undefinedstyle: () => { var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without calling require('console').

Warning: The global console object’s methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
//   Error: Whoops, something bad happened
//     at [eval]:5:15
//     at Script.runInThisContext (node:vm:132:18)
//     at Object.runInThisContext (node:vm:309:38)
//     at node:internal/process/execution:77:19
//     at [eval]-wrapper:6:22
//     at evalScript (node:internal/process/execution:76:60)
//     at node:internal/main/eval_string:23:3

const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);

myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err

const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err
@seesource
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100
log
('style-2');
} } ], { filename?: string | undefinedfilename: 'App.svelte' } ); // Svelte 3 logs: // markup-1 // markup-2 // script-1 // script-2 // style-1 // style-2 // Svelte 4 logs: // markup-1 // script-1 // style-1 // markup-2 // script-2 // style-2

例如,如果你使用 MDsveX,这可能会影响你 - 在这种情况下,你应该确保它位于任何脚本或样式预处理器之前。

¥This could affect you for example if you are using MDsveX - in which case you should make sure it comes before any script or style preprocessor.

preprocess: [
	vitePreprocess(),
	mdsvex(mdsvexConfig)
	mdsvex(mdsvexConfig),
	vitePreprocess()
]

每个预处理器也必须有一个名称。(#8618)

¥Each preprocessor must also have a name. (#8618)

新的 eslint 包(New eslint package)

¥New eslint package

eslint-plugin-svelte3 已弃用。它可能仍然适用于 Svelte 4,但我们对此不作任何保证。我们建议切换到我们的新软件包 eslint-plugin-svelte。有关迁移的说明,请参阅 此 Github 帖子。或者,你可以使用 npm create svelte@latest 创建一个新项目,选择 eslint(可能还有 TypeScript)选项,然后将相关文件复制到现有项目中。

¥eslint-plugin-svelte3 is deprecated. It may still work with Svelte 4 but we make no guarantees about that. We recommend switching to our new package eslint-plugin-svelte. See this Github post for an instruction how to migrate. Alternatively, you can create a new project using npm create svelte@latest, select the eslint (and possibly TypeScript) option and then copy over the related files into your existing project.

其他重大更改(Other breaking changes)

¥Other breaking changes

  • inert 属性现在应用于外部元素,以使它们对辅助技术不可见并防止交互。(#8628)

    ¥the inert attribute is now applied to outroing elements to make them invisible to assistive technology and prevent interaction. (#8628)

  • 运行时现在使用 classList.toggle(name, boolean),这在非常旧的浏览器中可能无法正常工作。如果你需要支持这些浏览器,请考虑使用 polyfill。(#8629)

    ¥the runtime now uses classList.toggle(name, boolean) which may not work in very old browsers. Consider using a polyfill if you need to support these browsers. (#8629)

  • 运行时现在使用 CustomEvent 构造函数,该构造函数可能无法在非常旧的浏览器中工作。如果你需要支持这些浏览器,请考虑使用 polyfill。(#8775)

    ¥the runtime now uses the CustomEvent constructor which may not work in very old browsers. Consider using a polyfill if you need to support these browsers. (#8775)

  • 现在,使用 StartStopNotifier 接口(传递给 writable 的创建函数等)从头开始实现自己的存储的人从 svelte/store 开始,除了设置函数之外,还需要传递更新函数。这对使用存储或使用现有 Svelte 存储创建存储的人没有影响。(#6750)

    ¥people implementing their own stores from scratch using the StartStopNotifier interface (which is passed to the create function of writable etc) from svelte/store now need to pass an update function in addition to the set function. This has no effect on people using stores or creating stores using the existing Svelte stores. (#6750)

  • derived 现在将在传递给它的虚假值而不是存储上抛出错误。(#7947)

    ¥derived will now throw an error on falsy values instead of stores passed to it. (#7947)

  • 删除了 svelte/internal 的类型定义,以进一步阻止使用那些非公共 API 的内部方法。其中大多数可能会为 Svelte 5 而改变

    ¥type definitions for svelte/internal were removed to further discourage usage of those internal methods which are not public API. Most of these will likely change for Svelte 5

  • DOM 节点的删除现在是批量的,这会稍微改变其顺序,如果你在这些元素(#8763)上使用 MutationObserver,这可能会影响触发事件的顺序

    ¥Removal of DOM nodes is now batched which slightly changes its order, which might affect the order of events fired if you’re using a MutationObserver on these elements (#8763)

  • 如果你之前通过 svelte.JSX 命名空间增强了全局类型,则需要将其迁移以使用 svelteHTML 命名空间。同样,如果你使用 svelte.JSX 命名空间来使用其中的类型定义,则需要迁移它们以使用 svelte/elements 中的类型。你可以找到有关执行 此处 的更多信息

    ¥if you enhanced the global typings through the svelte.JSX namespace before, you need to migrate this to use the svelteHTML namespace. Similarly if you used the svelte.JSX namespace to use type definitions from it, you need to migrate those to use the types from svelte/elements instead. You can find more information about what to do here