How I made a website with Svelte
johanronsse.be
johanronsse.be
I love the work of professional typographers, but tend to stay away from commercial Web fonts, because they like to include very restrictive terms in the font licences.
For example, you're only allowed to back up Klim fonts once, which we all know is no backup at all (https://klim.co.nz/licences/web-fonts/):
> You may make one (1) copy of the Web Fonts for back-up purposes only.
And I hope you don't take a week-long holiday away from your computer:
> At Klim’s request, You agree to provide an audit to confirm the Web Fonts You are consuming match Your Sales Receipt. Klim will give You at least 5 business days’ notice to complete the audit.
The Commercial licence is a bit better, but doesn't let you subset the fonts, which means your fonts might be 5 to 10 times as big as they should be, giving your users a worse experience (https://commercialtype.com/licenses/web):
> 10. You may not modify, adapt, translate, reverse engineer, decompile, disassemble, or alter, the Webfonts, the Font Software or the designs embodied therein.
I recommend using fonts under the SIL Open Font License, where you don't have to worry about this crap.
Anyway, nice work! I've been meaning to learn Svelte, and your site looks really good.
Another one with a greater selection but variable licenses:
Most small foundries have been bought out by Monotype and their licensing is now 100% subscription only. I was lucky to have purchased Univers and a couple of other fonts under their "Creative" license which bundled everything under a reasonable price.
Font foundries - listen up, if you want people to pay for your fonts, make the licensing model straight up simple - download fonts and off you go. Turns out that most people that are willing to pay for your font arent the ones trying to pirate them. Stop fucking them over.
Typography and calligraphy is an art form so it does justify the expense, but you've got to be able to actually use it.
> Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.
> Instead of using techniques like virtual DOM diffing, Svelte writes code that surgically updates the DOM when the state of your app changes.
That sounds like a perfect pitch for Angular. What's the difference between Svelte and Angular?
Starting in 2015, Angular v2+ uses an optimizing AOT compiler. [1]
It's only recently that it started producing multiple packages simultaneously, however (to serve up a package optimized for the client's web platform).
What Svelte does is precompile the UI update code[1], changing text nodes, attributes, children, targeting DOM nodes directly. Think Prepack[2] vs DOM diffing.
Angular compiler is certainly an optimizing compiler.
> Angular Ivy, yet to be released
Ivy became an opt-in feature of the Angular CLI earlier this year with Angular v8.
> AFAIK Angular still uses dirty checking
Ivy uses "dirty checking" too [1]. AFAIK Ivy and pre-Ivy operate on similar fundamental principals, which is why Ivy is a drop-in replacement.
[1] https://indepth.dev/what-every-front-end-developer-should-kn...
https://dev.to/maurogarcia_19/angular-vs-svelte-card-compone...
In addition, its reactive variables is a lot easier to use.
I take issue with opinions like this that are espoused as fact. I've built large apps in both Angular and React. The React code base needed everything that I got out of the box from Angular. The difference is that React had no one true way to do things which I suppose some people would consider a good thing. I don't.
Angular is a framework. Its not over engineered, its complete. You might not like its chosen abstraction but for people like me who just want to get shit done without needing to worry about plumbing and boiler plate, its really nice.
All that said, Svelte looks cool. I'll check it out. I think its a fair criticism to say that Angular has a steeper learning curve and if I can reap all the benefits with a shorter ramp up time, its worth adding to the tool belt.
It's almost comical. I can't believe how long that guide is and how many concepts Angular invented just to fetch some JSON from an http service.
WHY WRITE A SERVICE? This example is so simple that it is tempting to write the Http.get() inside the component itself and skip the service. In practice, however, data access rarely stays this simple. You typically need to post-process the data, add error handling, and maybe some retry logic to cope with intermittent connectivity. The component quickly becomes cluttered with data access minutia. The component becomes harder to understand, harder to test, and the data access logic can't be re-used or standardized. That's why it's a best practice to separate presentation of data from data access by encapsulating data access in a separate service and delegating to that service in the component, even in simple cases like this one.
Lets talk about what you get with HttpClient:
- Easy testing. Because its using the DI system, its very mockable. You can totally set this up with fetch or whatever behind a service but, well why? Its already done.
- Robust type safety. Again you can set this up with fetch, but why? Its already done.
- Integrated with rxjs/observables for data transformation, piping, and filtering. You can set this up with fetch but why? It's already done.
- Discoverable API because of the deep framework integration and type intelligence. You can set this up with fetch buy why? It's already done.
- HttpInterceptor is awesome for checking for things like auth tokens and such. You can set this up with fetch but why? It's already done.
Not specific to HttpClient but:
- AOT compiler means that unneeded code gets pruned keeping your bundles small.
- AOT compiler means that you literally can't compile incorrect code (but it provides an escape hatch if you want to live your life that way)
I can make this same argument for pretty much any module you throw at me. Like I said, Angular is _complete_. Is it the right fit for every situation? No! :) It's overkill for smaller projects but if you are building anything of sufficient complexity, you _will_ need all this stuff. The question is, do you want it to be something you had to roll yourself and didn't have time to document for your teammates or do you want something that did all the hard work for you and is ready for whatever you throw at it?
> Robust type safety. Again you can set this up with fetch, but why? Its already done.
Not sure what you mean here. Fetch has high-quality TypeScript bindings. For the rest it's mostly YAGNI. The boilerplate confuses new developers (try explaining what NgModule does to a junior dev just trying to build a simple page) and experienced developers know how to do this stuff themselves.
I have trained junior devs on Angular and I think it's a fair criticism to say it's a steeper learning curve. They do fine tho and as an added bonus they get introduced to concepts like IoC and the like which sets them up for other languages.
Experienced developers can set this stuff up its true. I have in fact. It's fun the first few times. Then you get annoyed and want to actually work on your problem domain. I'd much rather spend my time and brain power on that stuff.
The apps that I've built that had an established pattern and all the infrastructure needed from go tended to age better and tolerate changes to business requirements. The ones where we rolled it all hodge podge needed more extensive refactoring later.
I mean look: this really boils down to very different philosophies. You either go light and build as you go or go everything and the kitchen sink and deal with (what some would call) bloat. I think both have their pros and cons. No silver bullet and all that. You gotta look at the situation and make a call. The rest is just preference and gut instinct.
Angular uses an RxJS interface to XMLHttpRequest, which has a few advantages. For example, only relatively recently did fetch() (including polyfills) support cancellation.
That said, there's absolutely nothing that requires you to use @angular/common/http. Angular created it because developers have to solve those problems over and over, but it's just a library under the Angular roof; you can use fetch() function instead.
Angular is not overengineered, it's just feature-complete. vue is not "simple made easy", it just delegates lots of functionality to 3rd party, leaving the confused developer to read medium posts on the line of "axios vs. vue-resource".
I prefer the vue way, but it's a subjective personal preference and should basically be ignored by others.
I mean, it does run in a web browser.
The format should probably be broken up. But yeah covers a lot:
* HTTP, JSON, JSONP
* Request entities, response entities, headers
* Error handling, cancelation, and retries
* Authentication, logging, and other kinds of "middleware"
* XSRF
* Progress tracking
* DI and testing
* Type safety
> how many concepts Angular invented
Not a single one of those was invented by Angular.
The "weirdest" thing Angular does is use RxJS. But that would be more a criticism of Rx/FRP in general, not Angular specifically.
Whether good or bad, it seeks to be the solution to many problems (which you would have to solve in some way), hence it being a "framework".
I'd probably call that "opinionated" rather than "over-engineered."
It's commonly used with Angular CLI to have simple commands like "ng serve" and "ng build" to bundle your application. It also heavy handedly imposes constraints on the architecture of your application-- to some, that's a benefit. All Angular apps kind of look the same.
I followed the link to the css framework you used/developed, Ygdir, and I am not sure I understand it. Is the website a work in progress? Feel like it needs to explain with more details and examples what you mean by "convention-first". I agree what you said about utility first css but I'm not sure what makes Ygdir better
The problems I've seen with Tailwind in these projects are:
- Elements end up with messy, non-semantic class name strings like "m-4 mt-0 p-3 rounded bg-blue". This makes it much harder for non-technical teams to use out-of-the-box SaaS solutions for things like interaction tracking and A/B testing. (These apps often use element class names under the hood, so if you use Tailwind and change a CTA from rounded to very-rounded, the marketing guy will discover two weeks later that all his click-through metrics are wrong.)
- References to the utility classes wind up scattered in thousands of unrelated places in the codebase, making refactoring and changes to the CSS impossible. Like, if you ever wanted to remove the p-3 class (or change how much padding it represented), it would be almost impossible: you'd have to individually find and test/change all 9000 use sites, a task which is made even more difficult when developers write things like class={`p-${first ? 4 : 3}`}. At least one website I know is stuck on Tailwind 0.x pretty much indefinitely for this reason.
- Whenever you add a new color or padding amount or anything, you pay the full cost of generating all the variations (p-7, pt-7, bigscreen:pt-7, etc) up front in a CSS file that needs to be loaded before anything on the page can be rendered. (Sure, Tailwind might not generate 50K of variants when you add a padding value out-of-the-box, but once you've set those options it's impossible to un-set them because of the above point.)
This eventually leads to a codebase where no one wants to add, remove, or change CSS classes for fear of breaking something unrelated or destroying performance. In other words, it makes your CSS impossible to maintain.
IMO the problem here is tools trying to use CSS for something it’s not designed for. They advertise themselves as not requiring technical knowledge to use, but they’re selling a lie. Unless the marketing guy understands the structure of the site and the CSS there’s no way for him to be sure he’s tracking the thing he thinks he’s tracking - unless you’re instrumenting the CSS to help him out, and are committed to not doing anything that would break one of his selectors (or change its meaning, or reuse it for something else - and are you sure you know all the selectors he’s using, and that the automatic selectors the tool is creating are actually doing what he intends?).
Data attributes are probably the solution here, then CSS can be reserved for its intended use: controlling styles. But then the tooling needs a way to target those attributes automatically, otherwise you’ve “broken” the “no technical knowledge required” sell of the software they already licensed (without asking you for input...)
I don’t find your arguments about maintenance very compelling either. If you want an element with “p-3” to have more padding, just... change it to “p-4”. That’s the whole point! You don’t have to wrangle with the _semantics_ of the element. You style it exactly as you want. It’s akin to using the `style` attribute but terser. The only vector of change for the definition of a class name becomes the CSS spec itself. “p-3” === “padding: 3px” and cant _ever_ mean anything else (or it would have a different name).
I see your point about SaaS tools, but why can’t you just add a class name for that purpose alone? Seems simple enough to me.
I’ve tried just about everything when it comes to organizing CSS/styles and I have come to the conclusion that semantic naming is more trouble than its worth.
It will be interesting to read the comments on this early version but it's not really “released” yet.
One request: I read your gaming section eagerly and all the games you mentioned look super cool, but would you mind adding some links / details about each of them? I’m still not sure exactly which racing sim you’re talking about and the other screen shots look super cool but I had to google each game to figure out what the deal was. Not a huge deal but a small suggestion.
Otherwise - thanks! Excellent work.
* Assetto Corsa Competizione * Dirt Rally 2 * Gran Turismo: Sport
I should have added titles to them!
Is there some functionality on the pages that I'm missing?
This sort of site is a perfect testbed for such a framework.
If you're "exploring game engines" making a resume with one is probably not what you should reach for and if you're "exploring DAWs" your testbed shouldn't be generating a pure sine wave.
This sort of site is the opposite of a perfect testbed for a framework. This sort of site doesn't need JS, it doesn't need a framework, it barely needs CSS.
I’ve also literally seen someone use a game engine to build a resume on here, it was super cool and attracted a lot of interest
I wouldn't get too worked up about this: discussions about which jobs a tool lends itself well to can be very insightful.
It was also the tone the commenter posted in here and across this post that came across very condescending with a holier than thou feel. They also created this account today and have been flagged and had a mod post about their postings. So if they offered some helpful advice in a more constructive way their wouldn't be a need to tell them to stop.
Video: https://www.youtube.com/watch?v=qicEFB_XrQQ
This is much more about what the framework solves: UI as a function of the data, no spaghetti code full of DOM handlers and cross-references that are hard to follow.
Now I just used Svelte for this project, which is indeed a simple website which might not need this at all.
Still, I invite you to do similar transitions as I have between every page and on the homepage without a framework.
If there's some transition I didn't see because of the browsers I used (I tried two different browsers on two different devices), then it might be worth using the framework, but I maintain that I haven't seen the demo site show anything that couldn't be done with vanilla HTML and CSS.
It sounds like you're saying one should use a tool only for what it is meant for.
Many disagree.
> Then I remembered that I would probably need to redirect all requests to index.html.
Compare that to e.g. my blog (also the result of an experiment), which has the fast page changes you were looking for, but also works without Javascript, albeit with full page refreshes when switching pages: https://vincenttunru.com/
It goes by various themes:
- Can't see the forest for the trees
- resume driven development
- hype driven development
- brag shallow blog post driven development
- over-engineering
- sell courses driven development
etc...
In react, there are as many ways to do the same things as there are coders. And of course, some don't follow best practices and will put logic code in it.
Personnally I also find it easier to picture the resulting DOM structure because the stylee is forced to be declarative. Too often in react I have to look around a tag to know whats hapening, or I have to follow some nested map/filter/ternary chaining.
Very good react coders will not do that. They will use a lot of tooling and abstract formatting a lot. But they are few.
``` {#if invokeFunction()} <p>This function returned a truthy value!</p> {/if} ```
And with React do this:
``` { invokeFunction() && <p>This function returned a truthy value</p> } ```
and the result would be the same, a conditionally rendered string. I totally agree in the normalizing/formalizing how templates are build and the more verbose syntax in the Svelete example does make it super obvious. The in-line React example is obvious to me...but maybe that's because I've been writing js for so long.
Where I feel the cognitive overhead pain in looping. Svelete's docs say:
``` {#each collection as { vars }, i} <p key={i}> {vars} </p> {#/each}
```
For some reason, when I see this it rubs me the wrong way. I understand it...but my instinct is to just map over the collection like I would in a plain-old Node.js project.
``` { collection.map((vars, i) => <p key={i}> {vars} </p> } ```
I guess that saving a handful of keystrokes in exchange for super clearly expressing the intent may be a good tradeoff, even if my inclination is towards more terse code.
React has footguns like this because JavaScript expressions were not designed to be used as a templating language.
I'm reminded of https://gbracha.blogspot.com/2014/09/a-domain-of-shadows.htm....
<p v-for="(vars, i) in collection" :key="i">
{{ vars }}
</p>
Instead of: { collection.map((vars, i) => <p key={i}> {vars} </p> }
It's easier for me to picture what the first example is going to render because it makes the markup the hero, with code inside, while the second example is making JS the hero, with markup inside.But this example is not even touching the topic. A render function is rarely that simple. Now if you do maps, and filters, and ternary operators, and && / || pass trougth, and set several class conditionally, and pass an event and do preventDefault, etc., now you have a more real life example. And in react you'll get __a lot__ of JS, with very little markup. And you'll have either a lot of boilerplate, or a lot of dependencies to get helpers.
While in Vue you'll get mostly markup, with a little code inside. It will read from top to bottom as well. No needs to wrap stuff in arrow functions to get the event object. PreventDefault has a helper. Setting classes as well. I prefer that.
The IDE tooling is worlds better with JSX as well. Vetur has.. had a rough year.
And I must say that Svelte also caught my eye this year. I gave it a shot in their playground, and I was surprised how intuitive things are. Svelte as a compiler seems very natural an approach to building frontend apps and independent components.
My next project will be Svelte on the frontend (SPA), and Elixir+Phoenix+Absinthe on the backend. I personally think this will be a killer stack for 2020
(Next.js/Nuxt pendant based on Svelte, can also be used as static site generator).
But now I wanted to explore how one would build something like Sapper, this is why I went for base Svelte and then added a router. I now have pretty much what I used Sapper for and the setup is simpler.
Also, Sapper doesn't seem to be in active development.
>Also, Sapper doesn't seem to be in active development.
For three months or so, but I wouldn't worry about that, because just a thin layer on top of Svelte, and the maintainer is very active in the Svelte repo it seems. It may only get bumps if something breaks.
- automatic SSR (Server Side Rendering)
- possibility to export to server-less plain HTML/CSS/JS
- option to resource preload/fetching on mouseover/touchstart (a headstart of 300+ms)
- serviceworker cache: PWA, offline support, etc.
- session stores
Sure there is room for improvement (e.g. i18n), but it very useful and powerful already today.
Well.. With redux or Mobx you are largely updating existing DOM attributes in both Vue and React. The overhead in changing existing attributes on components is fairly minimal, and it's certainly not where the bulk of the performance issues in these systems are. It's also not where the value is.
The real value in Vue and React is reconciling data _graphs_ with the DOM _graph_. Unfortunately the need to reconcile the full graph, or even parts of the graph, is where a lot of the performance hit comes from. Particularly with lists; hence virtual scrollers. With the advent of proxies though, I would suspect both Vue and React could be retooled a bit to be more clever about how the DOM graph gets updated in response to changes in lists and other data graphs. More "surgical" so to speak.
Am I missing something or could the bulk of the performance gap be made up without needing to ditch React and Vue(throwing the baby out with the bath water so to speak)?
But, I really like the speed and user experience here. I may actually give it a try.
Is there an auto formatter that makes my code shift around and have one-true-style? This is a most for any long lived project as it avoid all bikeshedding discussions about style. We use Prettier for JS, and mix format for Elixir, at work.
[1] https://github.com/UnwrittenFun/prettier-plugin-svelte [2] https://github.com/sveltejs/eslint-plugin-svelte3
> "In 2018 I went content-first, but this year I went design-first. I more or less created all of the designs first, then implemented them as opposed to last year."
For somebody who believes that it's as fast to simply design in css, was this step worth it?
I do have to say I am quite fast with Figma as my day to day work is being a UI designer.
Figma seems like a tool worth learning, will have to dig in some more.
Although, this assumes you're in the initial design phase of something, not the typical designer->developer handoff where you basically just want to implement a specification someone handed you.
Jobs listings are cropping up in sundry places too. See for example: https://sveltejobs.dev/jobs/apple-senior-front-end-developer
(oh how far we've come - a simple best of list requires javascript)
Edited to add: to be clear, I mean while still using the framework.
You have to be a little careful about the interactions if you really care about it working with no JS (e.g. have an on:submit for a form and then also have a server-side route that it can POST to) but it's not too bad really.
This is clearly a technology exploration.
How can I explore new technologies if I impose limits that others don't set for themselves? The job market asks for JS skills. Look at my conclusion at the bottom of my post: I state that this might be a technology downgrade instead of upgrade.