Nova Tasks is a PWA written with Vue.js and TypeScript. It's a basic CRUD app for managing lists of things needing to be done. Because Nova is a PWA it can be installed on a device and used 100% offline.
I love the web and have often bragged about the power of progressive web apps, but I've never written one myself. I wanted to challenge myself to build a PWA while learning TypeScript develop an honest opinion about the technologies.
I love Vue.js because of it's baked-in solutions for routing, state management, and component styling - as well as the effortless 2-way data binding. The CLI makes standing up new apps with TS and PWA support very easy. Vue VS Code Snippets by Sarah Drasner is also a great tool for scaffolding TypeScript SFC components.
Once my app was up and running I set up a single Vuex store to house the task list. This was the first bit of fussing with TypeScript to get the build working - and a learning opportunity for understanding interfaces. I wrote a class for the task and a class for the Task List, which encapsulated all of the list logic for sorting, updating, and filtering.
I used the
localStorage API as my database for the app, which persists the task list across sessions. When the app is created it reads the local storage value, converts to JSON, and hydrates the task list. Any mutations to the app state also get saved off to local storage.
For complete offline support Vue's CLI tool makes it dead-simple. It's a box check when setting up the app, and the service worker and caching are all handled for you (no need to declare which files to cache manually). The web manifest file is configured through a manual Vue Config file as well, which further simplifies PWA creation.
Building a PWA was pretty neat. I wrote a custom prompt for the app as well that shows the "click to install" option for the app by hijacking the
beforeinstallprompt window event and showing a custom button. It was cool to see it work in Chromium-based browsers as the app install felt really natural. Relying on local storage for my DB is a bit of an issue with this approach, though, because the installed app has a different storage location. In the future I'd like to integrate some sort of cloud storage as a global source of truth.
There were a few CSS tricks I needed to pick up for styling the PWA too. When installed as a standalone app the iOS bar got in the way of my tabs. There's a CSS rule called
env(safe-area-inset-bottom) that can be used with a
calc to add padding to prevent conflicts.
I really enjoyed using TypeScript as well. I felt more confident in my code when writing, and liked adding the specificity for types and return values. Combining TS with Jest made my app feel amazingly solid. I only got bogged down a couple times trying to satisfy the build tools - but honestly it was not knowing what to reach for in the language (be it a custom interface or doing some type casting or null handling). In a previous job we used Lodash for null checks, I felt like TS was a little more elegant and robust for handling more than just nulls.