I have previously written a blog post about a knitting app I made for my wife
The app was written in reason, and I partially made it to make something useful for my wife, but also to learn something new. And that is indeed the case with KnitZilla V-2!
The new and improved KnitZilla is made with Laravel as a backend, and a typescript React app as my frontend.
Laravel is a very traditional rest framework, providing utilities for middleware, controllers, and routes.
I am mainly a frontend developer, and that sometimes make my choices concerning which backend technologies I use. I like express.js, because it is simple to get started, and simple to define routes. I steer away from more integrated solutions like asp.net core, because I find them more difficult to make sense of right off the bat.
Why Laravel then? I have a web hotel at a place where there is no CLI access.
It does, however, provide a MySQL database as well. Most of my traditional solutions can't be used since I use CLI access to run migrations and start servers.
With that boring stuff out of the way, let us dig into how I did it!?
First of all, scaffolding the laravel app. I mean, that was easy. After running some
apt install on my WSL I was ready to use the scaffolder.
By default, laravel uses blade templates as frontend rendering engine. For this, this does not fly.
By the very least, I need an experience that gives the same feel as the previous one, and that one worked offline. For that reason, I need an SPA with a service worker.
Very good, we now know how to serve our new web app. But how do we tell laravel that this is React, and how to parse the typescript files?
By default, Laravel uses webpack to bundle all frontend assets. Laravel also provides an easy API for working with webpack called mix.
Even though it's just a couple of lines here, it's not on by default.
npm run watch at this point bundles all the react and CSS assets and puts them in the public folder. From here, it is the job of the laravel framework to serve the web app on the correct paths.
Laravel provides different files for initializing different routes. All these different files have a specific middleware chain attached. For instance, you might not want to auth middleware to run on the first request to get the web app.
For this specific scenario, we have our web routes, which will be used to serve our frontend application, and our API routes, which will have API controllers for the data needed in the app.
To register our spa.blade.php file into laravel, we will create a controller and a new route in web.php route config.
return view(spa) will look in the blade template folder, and find a file called spa.blade.php and render that. This will serve the file previously shown.
Here we specify that on any route from the root, we want to serve the index function from the SpaController file.
The last part missing here is setting up the service worker.
I am using workbox from google to handle all my service worker related stuff.
When the bundling step is done, I will use the workbox CLI to find this template file and create the actual service-worker.js file that will be put in public folder which is statically available to the browser, and from there, it just works.