分析阶段是 Svelte 编译器管线中的第二个阶段,紧随解析阶段之后。此阶段负责验证组件结构、创建作用域、分析依赖关系以及收集将在后续转换阶段使用元数据。它执行语义验证、作用域创建、绑定检测,并为代码生成奠定基础。
有关在分析之前发生的解析过程的信息,请参阅解析阶段。有关如何将已分析的代码转换为最终 JavaScript 的详细信息,请参阅转换阶段。
分析阶段接收由解析阶段生成的抽象语法树 (AST),并执行深度分析以理解组件的结构和行为。其主要职责包括:
来源
分析阶段会生成一个全面的 ComponentAnalysis 对象,其中捕获了关于组件的所有必要信息。
来源
分析阶段的核心是作用域系统,它跟踪变量声明、引用和依赖项。Svelte 实现了一个复杂的作用域层级,它考虑了不同的变量类型,包括状态、props 和绑定。
作用域系统跟踪:
来源
分析阶段使用访问者模式来遍历 AST 并分析不同的节点类型。每个访问者处理特定的节点类型并相应地更新分析状态。
访问者系统使用分派机制为每个节点类型调用适当的处理程序。每个访问者:
来源
分析阶段会检测和验证“runes”——Svelte 的响应式原始类型,如 $state()、$derived() 和 $effect()。它决定组件是否处于“runes 模式”,并应用相应的分析规则。
分析 runes 时:
$props()来源
对于处于旧版模式(非 runes)的组件,分析阶段会分析带标签的语句($: x = y * 2)以:
响应式语句分析:
来源
分析阶段还会分析组件的 CSS 来:
CSS 分析:
来源
分析阶段实施全面的错误检查和警告生成,使用一个复杂的系统来:
错误和警告系统:
<!-- svelte-ignore name --> 注释来忽略特定警告来源
分析阶段收集关于组件的广泛元数据,供转换阶段用于代码生成。这包括:
| 元数据 | 描述 |
|---|---|
名称 | 从文件名或选项派生的组件名称 |
exports | 组件导出的值 |
runes | 组件是否使用 runes 模式 |
immutable | 组件是否将对象视为不可变的 |
accessors | 是否生成属性访问器 |
uses_props | 组件是否使用 props |
uses_slots | 组件是否使用 slots |
needs_context | 组件是否需要访问组件上下文 |
css.hash | 用于 CSS 作用域的哈希值 |
css.has_global | 组件是否具有全局样式 |
reactive_statements | 已排序的响应式语句映射(旧版模式) |
来源
分析阶段会以不同的方式处理旧版模式和 runes 模式组件:
| 功能 | 旧版模式 | Runes 模式 |
|---|---|---|
| Props | 来自 export let 声明 | 来自 $props() 调用 |
| 状态管理 | 来自重新赋值的变量 | 来自 $state() 调用 |
| 响应式 | 通过 $: 带标签的语句 | 通过 $derived() 和 $effect() 调用 |
| Store 订阅 | 通过 $store 语法 | 通过 $derived() 从 store 中 |
| 组件 exports | 所有 exports 均可访问 | 基于返回值的 export |
| Element 绑定 | 基于声明类型的双向绑定 | 使用显式信号的双向绑定 |
分析阶段会检测组件正在使用的模式(或使用显式的 runes 编译器选项),并应用相应的分析策略。
来源
分析阶段与其他编译器阶段的集成方式如下:
来源
分析阶段是 Svelte 编译过程的关键部分,负责理解组件的结构、验证其正确性,并准备高效代码生成所需的信息。它同时处理遗留模式和 runes 模式组件,为每种模式提供相应的分析。分析结果是一个全面的 ComponentAnalysis 对象,它捕获了转换阶段生成优化 JavaScript 和 CSS 所需的所有信息。