Migrating a web app from VueJS to Symfony UX: retrospective
The last couple of weeks, I have been refactoring the frontend of dikdikdik, one of my pet projects, that we use to track the scores when we play the card game 'wiezen'.
The release of version 3.0, in which I threw out VueJS in favour of Symfony Turbo and Symfony Live Components was announced yesterday, and in this blog post I look back on the refactoring, making some kind of roundup on what I like and dislike about the new frontend I created with those new symfony-ux tools.
So the idea of Symfony Turbo is to create modern interactive webpages, with php and twig, while using as little JavaScript as possible. I see two big advantges here:
First advantage: I can drop VueJS. Now don't get me wrong, I think VueJS is a great framework, and it helped me a lot when I needed my frontend to directly react on user actions.
But I wrote my original frontend with VueJS 2.6. And the current version of VueJS is version 3.2. VueJS 3 probably has a lot of cool features. And probably some ways of doing things in VueJS 2 are now deprecated. But I don't know those things, and I have little free time to study frontend frameworks for a hobby project. Keeping up with the current PHP and Symfony versions is hard enough already.
Second advantage: I don't have to convert my PHP value objects to json and back.
When I write software, I put a lot of effort in creating value objects. I try to create nice classes that enforce domain rules. And the IDE I use understands those classes, and helps me with code completion and static analysis.
The VueJS frontend I initially created, got its information from the backend by means of api calls. So the api converted the objects I put so many effort in, into json.
Then the JavaScript front-end code then needs to work with those json-objects, but the IDE doesn't know anything about the structure of these objects. So there's no autocompletion, no static analysis, and so my code ends up full of bugs.
Probably there are serveral solutions for this problem.
With Symfony Turbo, where the html on the frontend are just rendered twig
files, is certainly a viable one.
By using {# @var
-annotations in
the twig files, the IDE knows the type of the used twig-variables,
which helps me a lot.
So that's already a lot of coolness you get from Symfony Turbo. But Symfony Turbo alone didn't solve all my issues.
The score-app I am refactoring, has a lot of input fields and buttons. Initially, when moving over to Symfony Turbo, I had created a good deal of Symfony forms, because that's how Symfony Turbo handles user input, just like in a traditional Symfony application. But this lead me to a single controller action that was building and handling all those different forms, so it triggered the 'Single Responsibility Principle'-alarm in my head.
Luckily there's also something called Symfony Live Components.
Symfony Live Components are cool because they allow you to isolate
the code and twig for a single component in one class
and one twig file. E.g. I wrote a dealer select component,
that shows the list of active players, letting the user
indicate the player who deals the cards. For this, I need one
php class, DealerComponent
, and one twig file,
components/dealerComponent.html.twig
.
The cool thing is that
when the user selects a player, the live component can call
the code in that php class.
This is because the live component class is
actually a controller. In the case of the DealerSelectComponent
,
when a change-event is fired for the drop-down, the JavaScript magic
of the live components calls the controller action (the
live action) DealerSelectComponent::selectDealer()
.
So combining Symfony Turbo and Symfony Components, I managed to remove all VueJS, and still have a nice and rather readable codebase.
But of course it is not perfect. There are still some things I'm not 100% happy with.
- I don't really like the way I combine the event sourced back-end with the re-rendering of the symfony components in the frontend, see also my previous post.
- I had to introduce a new event
RenderingRequested
, to work around the problem that the frontend was re-rendered based on read models that weren't up to date. - I still have Symfony forms in place for the actual score logging and for logging corrections. I think it would be better to convert those to live components as well.
We'll see what the future brings; this application is always a work in progress. I'll keep you posted if something interesting happens to the project in the future. But I also want to remind you that dikdikdik is just a hobby project, and I don't always have a lot of time to work on it.
If I raised your interest for the project, you might want to take a look at the source code; it's available on gitlab under the conditions of the GNU AGPL.
Comments
Comments powered by Disqus