内容简介:Anyone whoThe Svelte compilation process can be broken down into 4-steps
Who is this for?
Anyone who
- is interested in the Svelte compilation process
- wants to get started in reading Svelte source code
Overview
The Svelte compilation process can be broken down into 4-steps
- Parsing source code into Abstract Syntax Tree (AST)
- Tracking references and dependencies
- Creating code blocks and fragments
- Generate code
Which sums out by the following pseudocode:
const source = fs.readFileSync('App.svelte');
// parse source code into AST
const ast = parse(source);
// tracking references and dependencies
const component = new Component(ast);
// creating code blocks and fragments
const renderer =
options.generate === 'ssr' ? SSRRenderer(component) : DomRenderer(component);
// Generate code
const { js, css } = renderer.render();
fs.writeFileSync('App.js', js);
fs.writeFileSync('App.css', css);
1. Parsing source code into AST
// parse source code into AST const ast = parse(source);
The Svelte syntax is a superset of HTML. Svelte implements its own parser for the Svelte syntax, which handles:
<div>
{ data }
{#each list as item}
The Svelte parser handles specially for <script> and <style> tags.
When the parser encounters a <script> tag, it uses acorn to parse the content within the tag. When the parser sees a <style> tag, it uses css-tree to parse the CSS content.
Besides, the Svelte parser differentiates instance script, <script> , and module script, <script context="module"> .
The Svelte AST look like:
{
html: { type: 'Fragment', children: [...] },
css: { ... },
instance: { context: 'default', content: {...} },
module: { context: 'context', content: {...} },
}
You can try out the Svelte parser in ASTExplorer . You can find the Svelte parser under HTML > Svelte .
Where can I find the parser in the source code?
The parsing starts here , which the parser is implemented in src/compiler/parse/index.ts .
Where can I learn about parsing in JavaScript?
My previous article, “JSON Parser with JavaScript” introduces the terminology and guides you step-by-step on writing a parser for JSON in JavaScript.
If this is the your first time learning about parser, I highly recommend you to read that.
2. Tracking references and dependencies
// tracking references and dependencies const component = new Component(ast);
In this step, Svelte traverses through the AST to track all the variable declared and referenced and their depedencies.
a. Svelte creates a Component instance.
The Component class stores information of the Svelte component, which includes:
- HTML fragment,
fragment - instance script and module script AST and their lexical scopes,
instance_scopeandmodule_scope - instance variables,
vars - reactive variables,
reactive_declarations - slots,
slots - used variable names to prevent naming conflict when creating temporary variables
- warnings and errors
- compile options and ignored warnings
b. Traverse the instance script and module script AST
Component traverses the instance script and module script AST to find out all the variables declared, referenced, and updated within the instance script and module script.
Svelte identifies all the variables available before traversing the template. When encountering the variable during template traversal, Svelte will mark the variable as referenced from template.
c. Traverse the template
Svelte traverses through the template AST and creates a Fragment tree out of the template AST.
Each fragment node contains information such as:
- expression and dependencies
Logic blocks, {#if} , and mustache tags, { data } , contain expression and the dependencies of the expression.
- scope
{#each} and {#await} logic block and let: binding create new variables for the children template.
Svelte creates a different Fragment node for each type of node in the AST, as different kind of Fragment node handles things differently:
- Element node validates the attribute , bindings , content and event handlers .
- Slot node registers the slot name to the
Component. - EachBlock node creates a new scope and tracks the
key,indexand the name of the list to be iterated.
d. Traverse the instance script AST
After traversing through the template, Svelte now knows whether a variable is ever being updated or referenced in the component.
With this information, Svelte tries make preparations for optimising the output, for example:
instance
e. Update CSS selectors to make style declarations component scope
Svelte updates the CSS selectors, by adding .svelte-xxx class to the selectors when necessary.
At the end of this step, Svelte has enough information to generate the compiled code, which brings us to the next step.
Where can I find this in the source code?
You can start reading from here , which the Component is implemented in src/compiler/compile/Component.ts .
Where can I learn about traversing in JavaScript?
Bear with my shameless plug, my previous article, “Manipulating AST with JavaScript” covers relevant knowledge you need to know about traversing AST in JavaScript.
3. Creating code blocks and fragments
// creating code blocks and fragments const renderer = options.generate === 'ssr' ? SSRRenderer(component) : DomRenderer(component);
In this step, Svelte creates a Renderer instance which keeps track necessary information required to generate the compiled output. Depending on the whether to output DOM or SSR code ( see generate in compile options ) , Svelte instantiates different Renderer respectively.
DOM Renderer
DOM Renderer keeps track of a list of blocks and context .
A Block contains code fragments for generate the create_fragment function.
Context tracks a list ofinstance variables which will be presented in the $$.ctx in the compiled output.
In the renderer, Svelte creates a render tree out of the Fragment tree.
Each node in the render tree implements the render function which generate codes that create and update the DOM for the node.
SSR Renderer
SSR Renderer provide helpers to generate template literals in the compiled output, such as add_string(str) and add_expression(node) .
Where can I find the Renderer in the source code?
The DOM Renderer is implemented in src/compiler/compile/render_dom/Renderer.ts , and you can check out the SSR Renderer code in src/compiler/compile/render_ssr/Renderer.ts .
4. Generate code
// Generate code
const { js, css } = renderer.render();
Different renderer renders differently.
The DOM Renderertraverses through the render tree and calls the render function of each node along the way. The Block instance is passed into the render function, so that each node inserts the code into the appropriate create_fragment function.
The SSR Renderer, on the other hand, relies on different node handlers to insert strings or expressions into the final template literal.
The render function returns js and css which will be consumed by the bundler, via rollup-plugin-svelte for rollup and svelte-loader for webpack respectively.
Svelte runtime
To remove duplicate code in the compiled output, Svelte provide util function which can be found in the src/runtime/internal , such as:
- dom related utils, eg:
append,insert,detach - scheduling utils, eg:
schedule_update,flush - lifecycle utils, eg:
onMount,beforeUpdate - animation utils, eg:
create_animation
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Docker——容器与容器云(第2版)
浙江大学SEL实验室 / 人民邮电出版社 / 2016-10 / 89.00元
本书根据Docker 1.10版和Kubernetes 1.2版对第1版进行了全面更新,从实践者的角度出发,以Docker和Kubernetes为重点,沿着“基本用法介绍”到“核心原理解读”到“高级实践技巧”的思路,一本书讲透当前主流的容器和容器云技术,有助于读者在实际场景中利用Docker容器和容器云解决问题并启发新的思考。全书包括两部分,第一部分深入解读Docker容器技术,包括Docker架......一起来看看 《Docker——容器与容器云(第2版)》 这本书的介绍吧!
XML、JSON 在线转换
在线XML、JSON转换工具
Markdown 在线编辑器
Markdown 在线编辑器