A demo of implementing the same app on three different platforms.
I created this project to
The project started as my step-by-step track following the
React tutorial. However, since the commit
labeled "Renamed the project
", it is different.
Here I implement the same mind boggling TTT game on three platforms: React, Svelte and Vue. I respectfully skip Angular for aesthetic reasons.
As in case of any real project, the Issues list plays an important role.
The original readme is here.
npx create-react-app my-app
- that was easy!
... but later, I deleted the original scripts from dependencies.I decided to use a unified webpack configuration and keep all different source modules in the same /src directory - kind of messy, but more fun - all three platforms use different filename extensions, after all.
This table shows the source modules line counts and production bundle size.
Board | Game | Square | boot module | total (lines) | loadable (bytes) | |
---|---|---|---|---|---|---|
React | 33 | 77 | 13 | 10 | 133 | 137 283 |
Svelte | 18 | 45 | 8 | 6 | 77 | 8 353 |
Vue | 19 | 61 | 18 | 5 | 103 | 68 815 |
Svelte bundle is by far the most compact of the three, while React seems to be the heaviest.
Svelte's source code line count also tends to be the smallest. This is an important factor of code readability and maintainability. Ok, one may argue, that Svelte code is less structured, but this is a matter of taste - after all - one can write spaghetti in any language, but lesser line count is a hard fact.
React implies the immutable state approach, while the other two do not. The pros and cons of this approach have been discussed widely, but small projects might not benefit much from it.
In the tutorial example, the immutable states are used to implement the time travel functionality (not implemented here yet), which is a variation of well known Undo/Redo. It works well for 9-square TTT, but for more complex practical applications, this is probably not a way to go.
React also features a prominent gotcha / feature - mutating any part of component's state triggers re-rendering of all its fields and sub-components.
In our TTT game, it means that everything gets re-rendered on every clock tick
and clicking an empty square will redraw all the other squares as well. The first problem
can be solved by moving clock stuff out of the root component state
, but fixing
the second one would involve some more substantial refactoring.
I do not think this is a horrific show stopper, but designing a performant app with React may actually be a bit more challenging, than expected at the first glance.
The WebPack configuration files here are structured for better readability. All three sub-configurations can be merged together without breaking anything. However, it's just a fun game here and using those three different platforms together in the same app is no smart idea in real life.