0 Shares 2879 Views

Building Responsive Web Application with SPA

Moiz Khan Sep 04, 2019

Single page web apps (SPAs) are rapidly becoming the solution for web application development. They give an extensive user experience and take complete advantage of responsive web design.

So, What Are Single-Page Web Apps?

Single-page web applications or SPAs are the software applications that can be accessed through web browsers and can be displayed on single webpage. They are able to dynamically update content as a user interacts with the app without needing to reload the entire page.

Single-page internet applications usually use HTML5 and Ajax features to build a seamless user interface that feels like a desktop or a native application.

If you are using single spa for the first time, it would be a little tricky for you as you will get to encounter terms like “application lifecycles”, “root application”, “loading function”, “child application”, and “activity function.”

The whole blog post will take you through setting up things and what decisions you have when you’re using a single spa. It’s based on Canopy Tax, where we walked from Angular 1 Monolith to Angular 1, React, and Svelte Polyglot.

Step One – Pick a Modular Loader

With module loader/bundler library you can use lazy load code. Webpack or JSPM is highly recommended if you are beginning from scratch.  And if you have set your mind for Webpack try to use Webpack 2 if you can as it provides support for promise-based lazy loading. It will make the process easy for you in the future as single spa needs your loading functions to return promises. In case if you are unable to use Webpack 2, getting simple spa to load your code slowly with Webpack 1 will demand some boilerplate code.

JSPM / SystemJS seems to have worse documentation than Webpack, but it’s a viable solution for module loading if you get past it. For a larger community, better docs Webpack is recommended. Otherwise, go for JSPM because Webpack has no plans to support dynamic runtime loading.

Step Two — Create a New HTML File

In the second step, create ‘root application’ which is just the stuff that initializes single-spa and it starts with an HTML file.  Even if a project already has an existing HTML file, try starting with a new one. With a new HTML file, you will get a clear distinction between what is there in your root application and child application. Keep your root application as much precise as you can as it is kind of a master controller of everything and could hold up.  As you wouldn’t be constantly changing both the root and the child applications. Here is a sample script for a single javascript file which will be explained in the next step.

Webpack is possibly the most prevalent use case, my code examples from here on, we will suppose that you’re using Webpack 2. The equivalent Webpack 1 or JSPM code has all the similar concepts and only a few minor code distinctions.

step-two-1

Step Three — Register Your Application

In the following step you need to conclude your root application by writing your “root-application.js” file.  The chief purpose of root-application.js is calling singleSpa.registerApplication(..)all the applications that are managed by single-spa.

You can think of single-spa as the operating system for your single page application, managing processes which of the processes are running at a provided time. Some of the kid apps will be active on the DOM at any time, and others will not. As the user explores the app, some apps will be unmounted from the DOM and others will be mounted on the DOM. The other way to look at this is that single-spa is a master router on top of your other routers. The other way to look at this is that single-spa is a master router on top of your other routers.

To do this, first npm install single-spa and then call the registerApplication function:

step-3-3

As single-spa is so very cool, an app called “cool-app” is created that will be lazy-loaded and mounted to the DOM when the URL hash starts with #/cool.

The loadCoolApp functionality is what single-spa demands a loading function. Inside of it, the import introduces a code-splitting point — Webpack would provide distinct code parts that would be lazy to be loaded with a single spa.

For any of your particular project, you wouldn’t have a hash prefix of “cool”, but establishing some kind of convention that makes it simple to decide which applications are active. It will make the maintenance of your activity functions simpler as you continue to add more child apps.

If you are planning to start with one child app then it would make sense to apply the function as () => true. Once you have more than one app you can think about getting fancier.

Lastly, calling start(). Is a must do in order to make things work. The main objective behind is giving control over performance and timing.

Step Four — Create “.app.js” File

In the following step, when you open your index.html file in the browser, a blank screen will appear on your screen.

One last step is building your app.js file. It is a configuration file that is created for each child application. It’s the code that’s loaded lazy when your activity function returns true. These are three things you need to consider in the app.js file:

  1. A bootstrap lifecycle
  2. A mount lifecycle
  3. An unmount lifecycle

Lifecycle here is referred to as a function or a group of functions that will be called by single -spa; you export these from the app.js file. Thus, every function must return the Promise so that the single spa learns when it is finished.

Here is a simple example:

step-4-a-1

Here you get to see a document document.getElementById and innerHTML = You might see the document at this point .getElementById and innerHTML= and think that you’ve been duped and maybe single-spa is really just a bad excuse for the UI component framework

Put All the Frameworks Together

It is not a UI framework but a framework for using other frameworks. So, using multiple of them would do great for single-spa. You may write child application in any framework, as it applies application lifecycle purposes. Each child application can be written in any framework, as long as it tries to implement application lifecycle functions. The mini-apps will then work together to develop the entire single page application.

Going back to our past instance, we may choose to write our “cool.app.js” as an Angular 1 app, and go for something else for future applications:

step-4-b-1

In the example provided above, we have made use of a helper library called single-spa-angularjs

In this example, we use a helper library called single-spa-angularjs which abstracts away the specifics of initializing Angular 1 apps.

You may have noticed that the lifecycles exported as arrays of functions rather than just functions. You can choose whatever is suitable for you.

Exporting an array of functions can contribute in your own custom behavior (for e.g. aboutToBootstrap and doneBootstrap) that will function before or after the lifecycles of Angular 1.

Every object in the array must be a function that returns a promise when you export an array. Single-spa will wait to resolve each promise before calling the next function in the array.

Step Five — Testing

It is time to refresh your page and you should have a functioning single-spa application. Now, go navigating to a URL that your child app is active for (#/cool) then navigate away from it. The page won’t refresh when you do that, but you should see your application mount to the DOM itself and then unmount it.

In case if you encounter any issues, try to narrow down whether the problem is in the root application or in the child application.

step-5-a-3

 

Adding a navigation menu could also be important, so you can properly verify all mounts and unmounts to the DOM.  If you want to improve your single-spa abilities, make the navigation menu a total child application whose function is () => true.

step-5-b-2

Once you are done verifying, remember that every application goes through these five stages.

CMMI logo