compiler-overview
Last updated
Last updated
svelte小记
解析:
解析源码成为抽象语法树(AST)
跟踪引用和依赖项
创建代码块和fragments
生成代码
大致可以用下图来解释:
如果用一段伪代码来实现,就是:
Svelte是HTML的超级。Svelte实现了自己的解析器用于Svelte语法,处理和。
并且,Svelte解析器区别对待了script的实例,和module script,。
Svelte的AST就像下面这样:
如果第一次看解析器,还是狠推荐去学习一下上文。
在这一步,Svelte会traverse这个AST去跟踪所有声明和引用的变量及依赖项。
Component
这个类,存储Svelte组件的信息,包含信息如下:
Component
会遍历(traverse)AST的实例脚本和模块脚本去 找出所有的声明,引用和更新的变量 。
Svelte会在遍历模版之前标识出所有可用的变量。当在遍历模版的过程中遇到变量时,Svelte会标记这个变量被模板引用了(referenced
)。
每个fragment节点会包含一些信息:
- expression and dependencies(表达式和依赖关系)
逻辑块({#if}
),mustache标签({ data }
),包含表达式和表达式的依赖项。
- scope
{#each}
和{#await}
逻辑块及let:
绑定,为子模板创建了新的变量。
Svelte为AST中的每种类型的节点创建不同的片段节点,因为不同类型的片段节点处理事情的方式不同
还有其他的一些
遍历模板后,Svelte就知道组件中是否更新或引用了某个变量。
有了这些信息,Svelte尝试为优化输出做一些准备,譬如:
确定哪些变量或函数可以安全的从instance
函数提升。
确定反应性的声明不需要反应。
Svelte更新CSS选择器,在必要时向选择器添加.Svelte -xxx
class。
在这一步的最后,Svelte有足够的信息来生成编译后的代码,下一个步骤再看。
渲染树中的每个节点都实现了render函数,该函数生成用于创建和更新该节点的DOM的代码。
Renderer
在源码的哪里可以找到不同的渲染器以不同的方式渲染。
DOM Renderer 遍历渲染树并在此过程中调用每个节点的render
函数。Block
实例被传递到render
函数中,因此每个节点都将代码插入到适当的create_fragment
函数中。
dom相关的, append
, insert
, detach
调度相关的, schedule_update
, flush
声明周期相关,onMount,
beforeUpdate
动画相关的,create_animation
怎么处理的呢?当这个解析器碰到标签的时候,使用去解析标签内的内容。当解析器碰到标签时,使用去解析CSS内容。
可以在试试Svelte的解析器。可以在HTML > Svelte下找到。
解析从开始。解析器在实现。
这个文章里有介绍,并指导一步步的写了一个JSON解析器。
HTML片段,
实例的脚本和模块脚本的AST及其词法作用域,和
实例的变量,
reactive的变量,
用以防止当创建临时变量时命名冲突。
和
和
Svelte会遍历模板的AST,并且会从这个模板AST创建一个树。
验证,,,
注册了一个slot名称到Component
创建了一个新的作用域和跟踪迭代列表里的key
,index
和名称,
可以从开始拜读。其中Component
实现在。
这个文章里有相关的知识点。
在这一步,Svelte创建了一个Renderer
实例,该实例跟踪生成编译输出所需的必要信息。取决于输出DOM还是SSR代码(), Svelte分别实例化不同的Renderer
。
DOM Renderer保持跟踪和一个。
一个包含代码片段去生成函数。
上下文跟踪一个列表,并呈现在编译输出的$$.ctx
中。
在renderer中,Svelte从片段树创建了一个。
SSR渲染器提供了一些帮助来在编译后的输出中生成,比如和。
DOM Renderer实现在,SSR Renderer实现在。
另一方面,SSR Renderer 依赖于不同的将字符串或表达式插入最终模板文字中。
render函数返回js
和css
,分别通过rollup的和webpack的用于bundler使用。
为了在编译输出中删除重复的代码,Svelte提供了util函数,可以在中找到它,例如:
参考: