菜单

分析阶段

相关源文件

分析阶段是 Svelte 编译器管线中的第二个阶段,紧随解析阶段之后。此阶段负责验证组件结构、创建作用域、分析依赖关系以及收集将在后续转换阶段使用元数据。它执行语义验证、作用域创建、绑定检测,并为代码生成奠定基础。

有关在分析之前发生的解析过程的信息,请参阅解析阶段。有关如何将已分析的代码转换为最终 JavaScript 的详细信息,请参阅转换阶段

概述

分析阶段接收由解析阶段生成的抽象语法树 (AST),并执行深度分析以理解组件的结构和行为。其主要职责包括:

  1. 创建作用域层级
  2. 跟踪变量声明和使用
  3. 识别状态、props 和 exports
  4. 分析响应式依赖
  5. 验证 CSS 使用
  6. 检测潜在的错误和警告

来源

组件分析结构

分析阶段会生成一个全面的 ComponentAnalysis 对象,其中捕获了关于组件的所有必要信息。

来源

作用域系统

分析阶段的核心是作用域系统,它跟踪变量声明、引用和依赖项。Svelte 实现了一个复杂的作用域层级,它考虑了不同的变量类型,包括状态、props 和绑定。

作用域系统跟踪:

  • 不同绑定类型(普通、状态、prop、store_sub 等)的变量声明
  • 组件中变量的引用
  • 变量的重新赋值和修改
  • 变量之间的依赖图
  • 函数作用域和块作用域

来源

访问者模式

分析阶段使用访问者模式来遍历 AST 并分析不同的节点类型。每个访问者处理特定的节点类型并相应地更新分析状态。

访问者系统使用分派机制为每个节点类型调用适当的处理程序。每个访问者:

  1. 分析其特定的节点类型
  2. 更新分析状态
  3. 可能触发额外的验证
  4. 跟踪依赖项和引用

来源

Rune分析

分析阶段会检测和验证“runes”——Svelte 的响应式原始类型,如 $state()$derived()$effect()。它决定组件是否处于“runes 模式”,并应用相应的分析规则。

分析 runes 时:

  • 验证 runes 的使用是否正确
  • 使用适当的响应式模型处理状态变量
  • 处理特殊情况,如 $props()
  • 为误用提供适当的错误消息

来源

响应式语句分析

对于处于旧版模式(非 runes)的组件,分析阶段会分析带标签的语句($: x = y * 2)以:

  1. 识别响应式声明
  2. 跟踪其依赖项
  3. 检测并报告循环依赖
  4. 为转换阶段排序

响应式语句分析:

  • 创建响应式声明之间的依赖图
  • 确保响应式语句按正确顺序执行
  • 检测可能导致无限更新循环的循环依赖
  • 为代码生成一个正确排序的响应式语句映射

来源

CSS 分析

分析阶段还会分析组件的 CSS 来:

  1. 检测全局与作用域样式
  2. 验证关键帧
  3. 跟踪 CSS 对组件元素的依赖
  4. 识别未使用的选择器(用于警告)

CSS 分析:

  • 创建 CSS 作用域的哈希值
  • 识别样式是全局的还是作用域的
  • 跟踪 CSS 关键帧以进行动画
  • 将 CSS 规则链接到元素选择器
  • 生成未使用的 CSS 选择器的警告

来源

错误与警告系统

分析阶段实施全面的错误检查和警告生成,使用一个复杂的系统来:

  1. 跟踪和报告语法错误
  2. 为潜在问题生成警告
  3. 允许通过注释忽略特定警告
  4. 根据用户配置过滤警告

错误和警告系统:

  • 提供带有代码引用的详细错误消息
  • 支持通过 <!-- 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 模式组件:

功能旧版模式Runes 模式
Props来自 export let 声明来自 $props() 调用
状态管理来自重新赋值的变量来自 $state() 调用
响应式通过 $: 带标签的语句通过 $derived()$effect() 调用
Store 订阅通过 $store 语法通过 $derived() 从 store 中
组件 exports所有 exports 均可访问基于返回值的 export
Element 绑定基于声明类型的双向绑定使用显式信号的双向绑定

分析阶段会检测组件正在使用的模式(或使用显式的 runes 编译器选项),并应用相应的分析策略。

来源

与其他阶段的集成

分析阶段与其他编译器阶段的集成方式如下:

来源

结论

分析阶段是 Svelte 编译过程的关键部分,负责理解组件的结构、验证其正确性,并准备高效代码生成所需的信息。它同时处理遗留模式和 runes 模式组件,为每种模式提供相应的分析。分析结果是一个全面的 ComponentAnalysis 对象,它捕获了转换阶段生成优化 JavaScript 和 CSS 所需的所有信息。