A framework for pure speed

The Svelte framework decided to shift the focus from a runtime-based system to a compiler-based system. This can be seen on their website, located at https://svelte.dev. On their front page, it even states the following:

Svelte compiles your code to tiny, framework-less vanilla JS – your app starts fast and stays fast.

By moving the steps from the runtime to the initial compile, we are able to create applications that will download and run fast. But, before we can start looking at this compiler, we need to get it onto our machines. The following steps should enable us to start writing code for Svelte (taken directly from https://svelte.dev/blog/the-easiest-way-to-get-started):

> npx degit sveltejs/template todo
> cd todo
> npm install
> npm run dev

With these commands, we now have a running Svelte application located at localhost:5000. Let's take a look at what the package.json has inside of it that got us up and running so fast. First, we will notice that we have a bunch of Rollup-based dependencies. Rollup is a module bundler for JavaScript that also has a rich set of tools to do many other tasks. It is similar to webpack or Parcel, but it is the tool that Svelte has decided to rely on. We will look at Rollup in more depth in Chapter 12Building and Deploying a Full Web Application. Just know that it is compiling and bundling our code for us.

It also seems that we got a sirv called (as can be seen in the package.json file). If we look up sirv inside npm, we will see that it is a static asset server, but, instead of looking for the files directly on the filesystem (which is quite an expensive operation), it caches the request headers and responses in memory for a certain period of time. This allows it to serve assets that may have already been served quickly, since it only has to look at its own memory instead of doing an I/O operation to look for the asset. The command-line interface (CLI) allows us to set up the server quite quickly.

Finally, we start our application in dev mode. If we look at the scripts section of the package.json file, we will see that it runs the following command: run-p start:dev autobuild. The run-p command says to run all subsequent commands in parallel. The start:dev command says to start our sirv server up in dev mode, and the autobuild command tells Rollup to compile and watch our code. This means that whenever we make changes to the files, it will automatically build for us. Let's quickly see this in action. Let's go into the src folder and make a change to the App.svelte file. Add the following:

//inside of the script tag
export let name;
export let counter;

function clicker() {
counter += 1;
}

//add to the template
<span>We have been clicked {counter} times</span>
<button on:click={clicker}>Click me!</button>

We will notice that our web page has automatically updated, and we now have a reactive web page based on an event! This is really nice when we are in development mode since we don't have to keep triggering the compiler.

The editor of choice in these examples is VS Code. If we head to the extensions section of VS Code, there is a nice plugin for Svelte. We can utilize this plugin for syntax highlighting and some alerts when we are doing something wrong. If the preferred editor does not have a Svelte plugin, try to at least get the HTML highlighting enabled for the editor.

Alright: this simple example already gives us plenty to look at. First, the App.svelte file gives us a similar syntax to Vue files. We have a section for JavaScript, a section for styling, and a section for our enhanced HTML. We have exported two variables, called name and counter. We also have a function that we are utilizing in the click handler of our button. We have also enabled a style for our h1 element.

It looks like the curly braces add the one-way data binding that we expect from these reactive frameworks. It also looks like we attach events in a simple on:<event> binding, instead of utilizing the built-in on<event> system.

If we now head into the main.js file, we will see that we are importing the Svelte file that we were just looking at. We then create a new app (it should look familiar to other reactive frameworks) and we target the body of the document with our application. On top of this, we are setting up some properties, the name and counter variables that we exported before. We then export this as the default export for this file.

All of this should seem quite similar to the previous chapter, when we looked at the class and module system that is built into the browsers. Svelte has just piggybacked on these similar concepts to write their compiler. Now, we should take a look at the output of the compilation process. We will notice that we have a bundle.css and a bundle.js file. If we first take a look at the bundle.css file that was generated, we will see something like the following:

h1.svelte-i7qo5m{color:purple}

Essentially, Svelte is mimicking web components by putting them under a unique namespace, in this case, svelte-i7qo5m. This is quite straightforward, and those that have utilized other systems will notice that this is how a lot of frameworks create scoped stylesheets.

Now, if we go into the bundle.js file we will see quite a different story. First, we have an Immediately Invoked Function Expression (IIFE), which is the live reload code. Next, we have another IIFE that is assigning our application to a global variable called app. The code inside then has a bunch of boilerplate code such as noop, run, and blank_object. We also can see that Svelte wraps many of the built-in methods, such as the DOM's appendChild and createElement APIs. This can be seen in the following code:

function append(target, node) {
target.appendChild(node);
}
function insert(target, node, anchor) {
target.insertBefore(node, anchor || null);
}
function detach(node) {
node.parentNode.removeChild(node);
}
function element(name) {
return document.createElement(name);
}
function text(data) {
return document.createTextNode(data);
}
function space() {
return text(' ');
}

They have even wrapped the addEventListener system in their own form so they can control callbacks and lifetime events. This can be seen with the following code:

function listen(node, event, handler, options) {
node.addEventListener(event, handler, options);
return () => node.removeEventListener(event, handler, options);
}

They then have a bunch of arrays that they are utilizing as queues for the various events. They loop through them and pop and run the events as they come up. This can is seen in the flush method that they have laid out. One interesting note is that they have seen_callbacks set. This is so that they stop infinite looping by counting methods/events that can cause an infinite loop. For example, component A gets an update that subsequently sends an update to component B, which then sends an update to component A. WeakSet may have been a better choice here, but they have opted to utilize the regular Set since it will be dumped once the flush method has finished.

One of the final functions that would be good to look at is the create_fragment method. We will notice that it returns an object that has a create function named c. As we can see, this creates the HTML elements that we had in our Svelte file. We will then see an m property, which is the mount function that adds our DOM elements to the actual document. The p property updates the properties that we have bound to this Svelte component (in this case, the name and counter properties). Finally, we have the d property, which relates to the destroy method and removes all the DOM elements and the DOM events.

Looking through this code, we can see that Svelte is utilizing a lot of the concepts that we would use if we were building a UI from scratch and utilizing the DOM API ourselves, but they have just wrapped it into a bunch of convenient wrappers and clever lines of code.

A great way to understand a library is to read the source code or see what it outputs. By doing this, we can find where the magic usually lies. While this may not be beneficial right away, it can help us write for the framework or even utilize some of the tricks that we see in their code in our own code bases. One way of learning is to imitate others.

Out of all of this, we can see how Svelte states that there is no runtime. They are utilizing the basic elements that the DOM gives us in some nice convenient wrappers. They also give us a nice file format to write our code in. Even though this may seem like some basic code, we are able to write complex applications in this style.

The first application we will write is a simple Todo application. We will be adding some of our own ideas to it, but it will be a traditional Todo application at the start.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.68.18