转换阶段是 Svelte 编译器管道中的第三个主要阶段。它接收来自分析阶段的已分析抽象语法树 (AST),并将其转换为用于客户端、服务器或两者兼有的优化 JavaScript 代码。此阶段负责生成高效的运行时代码,这些代码实现 Svelte 的响应式系统、DOM 操作和组件生命周期,同时保留原始 Svelte 组件的意图。
转换阶段是 Svelte 的编译时魔法真正发生的地方。它将组件的抽象表示转换为可执行的 JavaScript,这些 JavaScript 可以在状态更改时有效地更新 DOM。转换通过一系列访问器完成,这些访问器处理不同类型的 AST 节点并生成相应的 JavaScript。
来源
packages/svelte/src/compiler/phases/2-analyze/index.jspackages/svelte/src/compiler/index.jspackages/svelte/src/compiler/types/index.d.ts<svelte:options>)来源
packages/svelte/src/compiler/index.jspackages/svelte/src/compiler/types/index.d.ts转换过程涉及使用访问器模式遍历 AST,其中专门的访问器函数处理不同类型的 AST 节点。这种方法允许基于节点类型的模块化代码生成策略。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js转换阶段严重依赖于访问器模式实现,其中 AST 中的每个节点类型都有一个相应的访问器函数。这些访问器负责为该节点类型生成适当的 JavaScript 代码。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/SvelteElement.js常规 HTML 元素被转换为高效的 DOM 创建和更新操作。这包括处理静态和动态属性、类、样式和事件处理程序。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.jspackages/svelte/src/internal/client/dom/elements/attributes.js元素转换过程包括
例如,RegularElement 访问器packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js41-453 处理 HTML 元素的转换,通过
属性根据其类型以及是静态还是动态进行不同的处理
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.jspackages/svelte/src/internal/client/dom/elements/attributes.js属性转换代码处理几种情况
class 和 style 等特殊属性有专门的处理程序例如,set_attributes 函数packages/svelte/src/internal/client/dom/elements/attributes.js268-450 处理属性的运行时应用,仔细管理 HTML 属性和 DOM 属性之间的差异。
组件被转换以创建实例、传递 props、处理事件和管理插槽
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/component.js组件转换过程
{#if}、{#each} 和 {#await} 等控制流结构被转换为响应式代码,从而高效地更新 DOM。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js例如,EachBlock 转换packages/svelte/src/compiler/phases/3-transform/client/visitors/EachBlock.js 处理创建高效的迭代逻辑,当迭代数组更改时,该逻辑可以仅更新已更改的项目。
模板中的表达式(例如{variable})被转换为响应式代码。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js表达式的转换过程包括
例如,build_template_chunk 函数packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js39-120 处理模板内容的静态和动态部分的组合,决定何时使用模板文字而不是直接值。
转换阶段生成的代码与 Svelte 的运行时集成,以创建高效的更新机制。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js生成的代码通过诸如以下之类的实用函数与 Svelte 的运行时进行交互:
$.effect - 用于响应式和跟踪更新$.template_effect - 用于优化的模板更新$.set_attribute - 用于高效的属性设置$.child - 用于遍历和更新子元素转换阶段采用多种优化策略来生成高效的代码
模板的静态部分被识别并直接包含在 HTML 模板中,从而避免在运行时进行不必要的 DOM 创建。
复杂的表达式被记忆化,以避免不必要的重新计算。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js相关的更新被批量处理,以最大程度地减少 DOM 操作。
对于列表项中的重复结构,例如在{#each}块中,模板会被重用以提高效率。
根据上下文使用不同的 DOM 操作以获得最佳性能
setAttribute 用于标准属性class 和 style 属性的特殊处理来源
packages/svelte/src/internal/client/dom/elements/attributes.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/element.js转换阶段通常会生成四个主要的代码部分
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js自定义元素在转换过程中会获得特殊处理,以正确支持属性设置与属性设置
来源
packages/svelte/src/internal/client/dom/elements/attributes.js表单元素,如输入框、选择框和文本区域,会有特殊处理,以正确管理它们的值和选中状态。
来源
packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js转换阶段处理 TypeScript 注释,在代码生成阶段基本忽略它们,因为它们在分析阶段已经处理过。
转换阶段是将 Svelte 将已分析的组件结构转换为高效运行时代码的关键阶段。它
正是这个阶段使得 Svelte 的响应式方法独一无二且性能卓越,生成最少的代码,仅在状态更改时更新需要更新的部分。
来源
packages/svelte/src/compiler/index.jspackages/svelte/src/compiler/types/index.d.tspackages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.jspackages/svelte/src/compiler/phases/3-transform/client/visitors/shared/utils.js