The Svelte Compiler Handbook

栏目: IT技术 · 发布时间: 4年前

内容简介: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 Compiler Handbook

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

The Svelte Compiler Handbook

// 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

The Svelte Compiler Handbook

// 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:

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:

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

The Svelte Compiler Handbook

// 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

The Svelte Compiler Handbook

// 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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Spring

Spring

Bruce Tate、Justin Gehtland / O'Reilly Media, Inc. / 2005-04-12 / USD 29.95

Since development first began on Spring in 2003, there's been a constant buzz about it in Java development publications and corporate IT departments. The reason is clear: Spring is a lightweight Java......一起来看看 《Spring》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

SHA 加密
SHA 加密

SHA 加密工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具