In this article, I will talk about a complete full-stack environament that helps me to kick off my PWA projects very quickly.
“Write once, use everywhere”. I love this philosophy and I think this is the dream of every web developer: build an application that would be fully supported by all platforms (mobile, browser, desktop), without installation steps. This is a complex idea that Progressive Web Apps are trying to solve.
In this article, I will talk about a complete full-stack environment that helps me to kick off my PWA projects very quickly.
Before starting, I would like to share this github repository. This open-source project is a starter template that perfectly illustrates the points I will raise subsequently. So, if you need a concrete integration example, feel free to take a look. This stack is very opinionated, but it’s also what makes it powerful.
⚠️ Beware that the stack I am going to talk about does not necessarily fit your project’s needs.
Here are my needs:
I want a complete full-stack environment that helps me to focus on my developing skills to build Progressive Web Apps very quickly without compromising the best practices. Let’s do it step by step!
I will be very brief. We don’t want any database or REST API. Let me be more specific: We don’t want to manage them on our own. Why? Because it’s hard to host them and it’s more code to maintain. Nor do we want to deal with problematics like scaling etc. Keep in mind that what we want is *to be fast *during development!
Firestore** from firebase seems to be a pretty good option! Thanks to a client API, we will be able to read and write data from a cloud NoSQL database and firestore security rules will help us to provide access control and data validation. In addition, **Firestore offers an offline support for data persistence which is really interesting for PWAs. Firestore is also a realtime database. It means that I can listen to specific part of my data structure and get realtime updates on my application.
What if you need to run code in a secure context (not on client side)? For example trigger business logic when a client do a CRUD operation? To deal with these specific cases, we can use firebase cloud functions.
Cool! We’re done with a huge part of our stack, and be sure that we’ve just eliminated a huge amount of code. That’s what we want!
You really should use a third party (email, phone, social) to authenticate your user. It’s less code for developers to write, and it’s simpler for our users to authenticate.
Once again, we can use firebase to save some development time. Firebase authentication provides a lot of methods to handle authentication:
Firebase authentication providers
In a PWA context, I would recommend to write your own CSS and UI components. I think it’s hard to find a good lightweight UI component framework and our PWA needs to load fast. So if you decides to use a framework, be careful on how it will impact your application size.
Vuex** is the default state manager of Vue.js and it’s really simple to use. It comes with vue-devtools **which is an amazing browser extension to debug your application, trace events, and have a global view of what your data structure looks like in your app.
One of our prerequisite is to produce quality code because a PWA must be fast and lightweight. Here are the tools we can use:
Bundlesize report example
Lighthouse** (browser extension / chrome devtools): **A great audit tool that generates reports for your web app pages. A lighthouse report will rate your web pages on several topics (performance, accessibility, best practices and progressive web app). These reports will also give you advises to improve the negative points you might obtain.
Lighthouse report example
Code Coverage (chrome devtools): This tool will display how much code was executed vs. how much was loaded on a web page. This will help you to see which part of your code you could lazyload, and ship only the code a user needs.
Prettier*: *Code format is something really important in my opinion. I don’t mind using semi-colon or not. The only thing that is important to me is having the code uniform so anyone can read it the same way. Wether you like it or not, Prettier will format the code its way, and that’s what is great about Prettier.
Eslint*: *Use as many linter rules as you can (within reasonable limits), this will structure your code and helps you to go over best practices. If you don’t want to write your own set of rules, I suggest to use existing eslint configurations. I love the airbnb one because it’s very strict and complete.
If you’re not familiar with PWA, I suggest you to read this.
In this part I am not going to talk about how service workers works, or how to create a web app manifest. There is already great articles and documentation about it, so I’ll focus on tools you can use for a good start and give you some advices based on my experience.
This library brings the Web App Manifest to non-compliant browsers for better Progressive Web Apps. It also comes with some other cool features like creating dynamic splash screen images for IOS (not supported by default on IOS yet).
This plugin will help you to configure your PWA with Workbox, which is today the best way to handle service workers. By default, your service worker file is generated from a basic JSON configuration (you have access to) for more simplicity. But if you want more control over your service worker configuration, you’ll have to write a service worker file yourself (refer to the official documentation for more details).
Vue-cli-plugin-pwa comes with the library register-service-worker** that simplify service worker registration and exposes hooks for common service worker events like “updateFound” (when new content is available), “registered”** (when service worker has been registered) etc.
A PWA is not a good PWA if it cannot works properly without network connection. A clean offline management requires two things:
Now we’re done with the basic configuration!
But remember that you can still improve your PWA user experience. Here is some examples of improvements you could add:
Add to home screen modal for IOS
“New content available” popup
In many cases, Server Side Rendering is overkill. What I like about pre-rendering is that it won’t affect the way I’m writing my front-end app code or the architecture of my project, while getting almost all advantages of SSR. If you don’t know what pre-rendering is or when you should (not) use it, I suggest you to read this.
To pre-render our app pages, we can use prerender-spa-plugin. In short, this plugin fire up a headless browser, load your app’s routes and save the result to static HTML files. It means that all of my application will remain static, so we could easily host it.
Now we need to host our static website, and I think that you start to understand that I do like firebase 😉.
Firebase hosting will help us to quickly deploy our PWA to a CDN that will serve our content over a secure connection (HTTPS is required to use service workers in production).
Cool! We’re almost done. But we are lazy, and there is some parts that we can automate.
CircleCI is a great platform that will help us to run our tests, check code with our quality tools and deploy to firebase hosting when we push code to the remote repository. Here is the workflow we want:
CircleCI workflow example
Here is the CircleCI configuration file that corresponds to the above workflow.
With this full-stack solution, the only thing we need to care about is writing our PWA code, and this is exactly what we were looking for. To summarize:
As already mentioned, checkout this github repository (that Thomas Betous and I have been working on) if you’re interested in building a PWA and don’t know where to start, or if you just want a concrete example of the stack I presented in this article.
A comprehensive step by step tutorial on building simple chat web app using Vue.js and Google Firebase Realtime Database with multiple chat rooms and users
A comprehensive step by step tutorial on build Firestore Database CRUD Web Application using Vue.js 2 and Firebase.