Pain and Tears in Svelte 3

Instead of the foreword



The article will be useful to those who, just like We decided to try Svelte in a live project. Our small company received an order to develop a web admin for a service with a backend on Mongodb Stitch. In the last couple of years, frontend We write in React or Vue (depending on the size of the project and whether ReactNative is needed), but after hearing about the beauty of Svelte, we decided to try it to understand for ourselves whether it is good. And maybe we should also use it instead of Vue or React? ..



Who is Svelte?



image



If in a nutshell - this is the new js framework (but he doesn’t consider himself like that), which is the killer of React and Vue, and blah, blah, blah ... In my article I want to consider Svelte not just what it is cool "under the hood", but from the point view of the convenience of its use in a real project.

We do not make cars, we drive them and we have evil customers with no less evil terms.



Tutorial



The first thing you start learning about a new language or framework is a tutorial on the site. At Svelte, this is Svelte.dev/Tutorial .



Unfortunately, part of the tutorials simply does not work on the site in the preview, while it is not entirely clear whether it works in reality or not. You have to spend time and check yourself manually, since it is not clear whether the tutorial is out of date or something went wrong on the Svelte website. And it really takes a lot of time.



UI Kit and Styles



image



Finding a UI Kit for Svelte was a separate pain for all of us. I wanted to exclaim: “At least Material, Bootstrap ... at least something ...”.



Only sveltematerialui.com and svelteui.js.org were found, which at the moment looked very raw.



With a simple import of <Button/>



from it, an error fell out of the package during assembly, there was no time to solve the ui kit error.



Having run quickly through the documentation, I decided to abandon it in favor of Vanilla import from CDN.



I wanted to use Material UI in the project, since it’s possible the admin panel will also be used from a mobile device, and Material is very suitable for this (in my opinion, it looks even worse on the desktop).



Using JS without a UI Kit mentally brought me back 10 years ago) Class locomotives and kind nostalgia).



Due to the fact that Svelte works with the DOM “in a different way”, MaterialUI began to get out all sorts of nasty things related to how the UI components that are added via js to dom are displayed. For example, a simple spinner is displayed every other time:



image



After a long search, what went wrong, it turned out that the spinner in the Material UI is added via JS after the document is ready (onLoad) but after this event, Svelte starts its addition to the DOM and the JS script Material simply does not see it since the event was before.



This had to be treated by adding to the parent component of Svelte:



  afterUpdate(() => { componentHandler.upgradeDom(); });
      
      





Stylization



With styles everything is very clear, we stuff all the styles as in Vue. You write the style and everything is in order, and then write the UI component (since you do not have UIKit) which should take props parameters, for example width and height, and logically do it like this:



 <script> export let width = '20px'; export let height = '20px'; </script> <style> .loader { width: { width }, height: { height }, } </style>
      
      





And ... no, in the style you can’t insert variables. You can get out of this situation through “ReactWay” and make dynamic styles in the “script” as variables or functions with style return.



As a result, we again have porridge, part of the style in the style part in the script . Pure code will be obtained only if you do not have parameters in the styles or you only have dynamic parameters and they are only in the script .



Routing and Routers



Without a normal router, you cannot even make one page app.



React, Vue when scalping the 'Hello World' project already comes with a router in the box (or you can select it). But like everything in Svelte, this is not easy.



You need to choose a router yourself, and even between very similar solutions. In truth, there are only two github.com/EmilTholin/svelte-routing and github.com/kazzkiq/svero routers so far.



Both are very similar, but I chose the first one, I chose it by the number of stars (yes, I know, I'm a terrible person).



So let's start embedding it in our MDL.



Wrap everything in <Router url = "{url}"> and add <Link /> for the links from the navigation.



image



Go to the preview and see what happened.



But it turned out that Svelte’s childhood illnesses continue and classes cannot be transferred to <Link />. A reasonable question arose and how will you stylize it?



Apparently this is still in issues for the router.



Fortunately, we can bind our usual a href = '' to the router by specifying use: link for which special thanks.



Mistakes



Unlike React, which simply will not let you create a bundle and will scream strongly about an error, Svelte will perfectly collect everything with an error. At the same time, if you forgot something, install npm install or export, everything will be fine and just show a white screen (Incidentally, this was the case in the first versions of React).



In React and Vue, We used to see such errors at the build or lint stage.



As a result, you will have to catch errors in two places. In fairness - this is in React and Vue, but much less often and such obvious errors are caught at the lint stage.



Svelte just needs naming convention



You will encounter this problem quite often - with the absence of a naming convention.



For example, back to the router.



There is such an import:



     import { Router, link, Link ,Route } from "svelte-routing";
      
      





What of this Link and link ? Even in such a small project like mine, there was already confusion with the lack of naming conventions in projects used in Svelte.



Of course it should have looked like this in ReactMan's eyes:



 import { Router, useLink, LinkComponent ,RouteComponent } from "svelte-routing";
      
      





In Svelte there is a semblance of ref as in react, this is a reference to a dom element or component.

The official tutorial tells us to do it like this:



 <script> let dialog; </script> <dialog bind:this={dialog} class="mdl-dialogÂť />
      
      





And if you have 15 variables in the component?



 <script> let loading; let pins; let dialog; let stitch; </script> <dialog bind:this={dialog} class="mdl-dialogÂť />
      
      





Where and which of these are really variables, and where are the links to components or elements?

I would modify the tutorial and make the examples more correct from the point of view of beginners and their convention of variables (see the React Tutorial for a good example). If you let the vinaigrette do variables, it would be nice if the linter or bundler swore at such a vinaigrette, as for example, this was done by golang.



 <script> let dialogElement; </script> <dialog bind:this={dialogElement} class="mdl-dialogÂť />
      
      





Another example of “life” when you receive some data in the component function and this data must be sent to your View , where some variable is screwed to the part of the UI element. And it looks with us (or rather, with our programmer) like this:



  async function ReloadPins() {        loading =  true;        pins = await getAllPins();        status = 0;    }
      
      





When I opened its code, it immediately “became clear” to me that there is a variable which is state and which of them is attached to our UI .



Just kidding, of course, nothing is clear. Moreover, the state is not even clear, or is it just an auxiliary variable. In React, this is decided by state, which at least somehow brings clarity.



What has changed where and who did it?



The variables inside the Svelte component are global and they change everywhere (hello Angular).

But there is good news, they are global within one component (while Angular), therefore this change of all and by all is not so scary inside one component.



At the same time, you save time on the “beauty” of the code and don’t think about what you need to make state a variable, but what to leave inside the function (hi React) - you have everything and everywhere.



image



As a result, you quickly write the components, but it can be very difficult to understand what the junior wrote in this “salad” a few days later when he already forgot (sometimes even his name). Because of this, it will be impossible to understand what is inside without a clear organization of the code within the project or team.



Bind Stitch



Stitch is a great thing, and I’ll definitely tell you more about it, and compare it with peers, measure the tests in production in my next article, and now it's more about Svelte.



To use Stitch you will have to go along the “Vanilla” path and insert:



 <script src="https://s3.amazonaws.com/stitch-sdks/js/bundles/4.4.0/stitch.js"></script>
      
      





Since when using npm and a normal import package, the buffer error problem begins.



I don’t know if this is connected with the Svelte collector or Stitch itself, or something else, but I didn’t have time to pick it and I just had to add a script with import, after which everything worked successfully.



These are the main problems we encountered while working with Svelte. And to be honest - in general, we did not like it, and nobody ...



What is the result:



Why do you need Svelte?





Based on the latter, I don’t understand at all why Svelte maintainers are going to make TypeScript support? We love Svelte just for “shooting at the legs” and TypeScript in my opinion is like all-terrain tracks for the Svelte sports car. And you know, after working with Svelte, I realized how much JS has changed in recent years, and that it is no longer JS.



Svelte gives the opportunity to work in the same old and lamp JS, without PropTypes, Flow and TypeScript.



What did I like?





Why not use Svelte?






All Articles