Thinking in Apps with FrintJS
--
When you build something with FrintJS, you do it by creating an App first. The primary app that you create is called a “Root App” by convention.
While having a single Root App is a requirement, FrintJS also gives you the APIs to create and register multiple Child Apps to your Root App.
Why create Child Apps?
All applications, given enough time, grow big. Concept of Child Apps in FrintJS help you break your large monolithic applications into smaller isolated Apps, that you can load and register (and optionally render) on demand.
If you are building something for the browser, imagine loading each App via their own bundle asynchronously (like app1.js
, app2.js
, and so on).
Having smaller Apps means they are responsible for doing their own thing only and easier to manage in the long run.
Once you get the providers sorted out well in your Root App, you can even distribute the work of Child Apps to separate teams simultaneously with ease.
An example application
Think of a big project management application. It may have these features:
- Users management
- Todo list management
- Calendar for events management
Let’s break it down into smaller Apps
If you were building this big application with FrintJS, you could break it down into multiple Apps as follows:
Root
: The primary base of the application (Root App)Users
: Child App for handling usersTodos
: Child App for all things todosEvents
: Child App for managing everything related to calendar/events
Each Child App could have its own set of providers (dependencies of your App), and other Child Apps do not need to share them unless really needed.
frint-cli
itself is built with FrintJS, where the primary$ frint
command is a Root App, and sub-commands like$ frint help
and$ frint new
are separate Child Apps.
Creating and registering Child Apps
Let’s create our Root App first:
import { createApp } from 'frint';const RootApp = createApp({
name: 'MyRootApp',
providers: [
{
name: 'foo',
useValue: 'foo value here',
},
],
});const app = new RootApp();
Now that we have created a Root App and also instantiated it, we can start creating Child Apps:
const TodosApp = createApp({
name: 'Todos',
});
We can register the Child App as follows:
app.registerApp(TodosApp);
And that’s it. The Todos
Child App is now registered to the Root App.
The instance of Todos
app can be obtained as follows:
const todosApp = app.getAppInstance('Todos');
Passing providers down from Root App to Child Apps
It is very likely that you have some really important providers defined in your Root App, that you would like your Child Apps to access.
FrintJS allows providers to be “cascaded” when they are defined in Root Apps.
For example, in above code example, we noticed that Root App has a provider named foo
. To make it accessible to Todos
Child App, we can update your Root App definition slightly:
import { createApp } from 'frint';const RootApp = createApp({
name: 'MyRootApp',
providers: [
{
name: 'foo',
useValue: 'foo value here',
cascade: true,
},
],
});const app = new RootApp();
Because of this additional cascade
property, the provider foo
will be made accessible in all registered Child Apps.
The Todos
app could access it like this:
const todosApp = app.getAppInstance('Todos');todosApp.get('foo'); // `foo value here`
You can read more about it in our documentation.
What about rendering Child Apps?
I intentionally didn’t touch this topic in this post, since this would involve dealing with rendering libraries like React or Vue.js.
FrintJS has integration with both React and Vue.js by the way!
I highly recommend reading about the concepts of Components and Regions in the FrintJS documentation website, which will describe everything you need to know with code samples too.
You can also take a look at a working example dealing with multiple Child Apps here.
I have covered the topic on rendering Child Apps with React.js, in another blog post here.