Just yesterday
, the 2nd version of the young but very promising
SvelteJS framework was
released . The version is major, which means it contains not only new features and fixed bugs, but also corresponding “breaking changes”. What's new offers developers a new version and why
Svelte is even better, read under the cut.

If suddenly, for some unknown reason, you do not know what
Svelte is and why it is not
“yet another javascript framework” . I suggest first
catching up to better understand what they mean.
New template syntax
The most obvious and global change in the new version is a radical change in the syntax of the templates. Rich finally decided to get rid of "uso" -like syntax in favor of a more concise version:
It was')
{{#if foo}} {{bar}} {{else}} {{baz}} {{/if}}
It became {#if foo} {bar} {:else} {baz} {/if}
Obviously, the syntax is visually simpler and cleaner. The changes affected all designs in the templates, including the special elements of
Svelte :
It was <:Component {foo ? Red : Blue} name="thing" /> {{#if foo}} <:Self /> {{/if}} <:Window on:keydown="handleKey(event)" /> <:Head> <title>{{post.title}} • My blog</title> </:Head>
It became <svelte:component this="{foo ? Red : Blue}" name="thing"/> {#if foo} <svelte:self/> {/if} <svelte:window on:keydown="handleKey(event)" /> <svelte:head> <title>{post.title} • My blog</title> </svelte:head>
The previous syntax of special elements was too unusual and most code editors did not cope with its highlighting. The new syntax resembles the syntax of
namespace from
XML and is much better perceived by editors.
We must pay tribute to Rich and separately note that all changes were
actively discussed with the community, and some of
my suggestions were included in the final version of the syntax and, like, even contributed to simplifying the parser.
In general, there are a lot of changes in the syntax and this could be a problem for migration to the new version, if not for the
svelte-upgrade utility, specially created for the automatic upgrade of
Svelte components. A complete list of changes can be viewed
there .
Good, Rich! Goodbye "mustache"!

ES6 only
Since
Svelte is primarily a compiler, it is worth first to note that the final code of the previous version was compiled in
ES5 . Therefore, to support
IE11 and other "progressive" versions of browsers, there was no need to communicate with transpillers like
Babel or
Bublé .
But in the courtyard of 2018, and so that the compiler could produce a more optimal and even more compact code, it was decided to abandon support for
ES5 . In other words,
Svelte now compiles the components in
ES6 and we will have to use a transpiler if we need support for older versions.
I myself fully support this approach. Moreover, it is not difficult for anyone
to connect
Babel to a Webpack or
Rollup . Especially when you consider that using
Svelte without it will still not work. ;-)
Actions
I still do not understand why this feature is called
actions , but for myself I decided that the native speakers know better. Although for me personally - this is not an obvious name.
Anyway, the feature is useful. In fact, this is a kind of hook that works when an element is rendered in the
DOM . For this, a new
use directive has been introduced
: <img src="placeholder.jpg" use:lazyload="{ src: 'giant-photo.jpg' }">
And the corresponding section in behavior:
export default { actions: { lazyload(node, data) {
An action is a function that takes as its first parameter the element to which the directive is applied, and the data that was passed to it. The function must return an object with the required
destroy () method, which will be called at the moment when the element is removed from the
DOM . Also, an object can contain an optional method
update () , which will be called every time when the data associated with the action has been changed.
In general, if there is a need to make manipulations with the
DOM directly, past the reactivity of
Svelte , actions allow you to do this conveniently and provide a mechanism for synchronizing these changes.
New Life Cycle Hooks
In the previous version there were only 2 hooks:
oncreate () and
ondestroy () . Now we also have 2 additional hooks responsible for working with the state:
export default { onstate({ changed, current, previous }) {
As you can see, each hook accepts an object with 3 properties:
- changed - includes keys that have been changed in the stack. Used to test
- current - modified state
- previous - previous state
You can use it like this:
export default { onstate({ changed: { foo }, current, previous }) { if (foo) { console.log('foo has changed from %s to %s', previous.foo, current.foo); } } };
Or even like this:
component.on('state', ({ changed, current, previous }) => {...});
In connection with this important change,
observe () was moved from the core to the
svelte-extras add
-on package . Therefore, if you like the previous syntax, you can simply connect the appropriate method from this package:
import { observe } from 'svelte-extras'; export default { methods: { observe }, oncreate() { this.observe('foo', (current, previous) => {...}); } };
If we recall that Rich, as the creator of
Rollup , is a fan of
tree-shaking , this approach immediately becomes obvious.

Spread attributes
Yes, I know, it was spied on by
JSX , but essentially it does not change. Many voted FOR and now
Svelte can also:
<Child {...childProps} />
Other changes
Important changes have occurred in some of the existing
api framework. Here are the main ones:
The get () method no longer accepts parameters and always returns the entire state of the component:
It was const foo = this.get('foo'); const bar = this.get('bar');
It became const { foo, bar } = this.get();
This is cool and we can use
destructuring assignment to determine the necessary properties. Moreover, now this method has become more similar to its antagonist, the
set () method, which in the previous version accepted only the object:
this.set({ foo: 1 }); const { foo } = this.get();
In general, I have the impression that
Svelte is increasingly inclined to use
RORO in its interfaces. A full transition to
ES6 only contributes to this.
The same observation confirms the new syntax of the calculated properties:
It was export default { computed: { d: (a, b, c) => a = b + c } };
It became export default { computed: { d: ({ a, b, c }) => a = b + c } };
At first glance, a strange and not very useful change (perhaps RORO), but in fact the
next step will be the possibility of creating a calculated property dependent on the entire state of the component. For example, to filter it or otherwise manipulate it, as well as transfer it to child components using a spread attribute, in the following way (as long as it does not work):
<Child {...props}/> <script> import Child from './Child.html'; export default { components: { Child }, computed: { props: state => { const { unwanted, alsoUnwanted, ...props } = state; return props; } } }; </script>
I think many understand how cool it is. I hope Rich will fix this feature in the near future.
Custom event handlers should now return destroy () instead of teardown () for consistency:
It was export function eventHandler(node, callback) {
It became export function eventHandler(node, callback) {
Svelte no longer renders component attribute values ​​to type.
Now you need to explicitly specify a type other than a string using an expression. Most of all it concerns numbers:
It was <Counter start="1"/>
It became <Counter start="1"/> <Counter start="{1}"/>
I think the meaning is clear. A wise decision.
In templates, the methods of the store can now be called using the $ prefix.
It was <button on:click="store.set({ clicked: true })">click me</button>
It became <button on:click="$set({ clicked: true })">click me</button>
In the previous version, only data from the store was available through the
$ prefix.
Tudushechka

For clarity, dashed off his own "tudushechku." In it, I tried to reflect the maximum of new
Svelte features that can be applied to this task, again for clarity.
Tudushechka can
CRUD over tasks, emulate asynchronous interaction with persistent state (storage, backend, etc.) and querying by one parameter - type of todo-sheet (work, family, hobby), as well as light animations. Works primitive, spelled quickly. Everything I love))))
→
FeelThat's all, thank you all! Good Friday and weekend!
UPDATE:
Who is interested in Svelte and would like to follow its development -
welcome to the Russian-language telegram channel
SvelteJS . We will be glad to you!