Micro Frontends with SSR in Ara-Framework
Hello everyone, my name is silverbirder. My latest interest is Micro Frontends.
https://silverbirder.github.io/blog/contents/microfrontends
I'm currently learning how to approach Micro Frontends using a framework called Ara-Framework.
What is Ara-Framework?
Build Micro-frontends easily using Airbnb Hypernova
Ara-Framework uses the Hypernova framework developed by Airbnb to build Micro Frontends.
What is Airbnb Hypernova?
A service for server-side rendering your JavaScript views
Briefly, Hypernova is a library that returns rendered results (HTML) when you pass it data. This has the advantage that data construction and rendering can be clearly separated.
Ara-Framework architecture
The architecture diagram of Ara-Framework looks like this
The components are as follows. (Also explained on the official page at ↑)
- Nova Proxy.
- Proxies browser access to Layout.
- Parses the HTML returned from Layout and queries the Nova Cluster for Hypernova placeholders, if any.
- Embeds the HTML returned from Nova Cluster into Hypernova placeholders and returns the HTML to the browser.
- Nova Directive (Layout)
- Constructs the overall HTML, embedding Hypernova placeholders.
- Node.js, Laravel and Jinja2 are supported.
- Nova Cluster.
- A cluster that manages Nova Binding.
- Located between Nova Proxy and Nova Bindings.
- Nova Bindings (Hypernova)
- It is passed data and returns the result of rendering HTML. (Hypernova is used here).
- React, Vue.js, Angular, Svelte and Preact are supported.
By clearly separating Layout and Rendering (Nova Bindings) in this way, we feel that independence and scalability are good. A cache layer between each layer is also expected to improve performance.
For more information, see the official page.
Ara-Framework sample code
We have actually used Ara-Framework. The sample code is given below. https://github.com/silverbirder/micro-frontends-sample-code-2
The package.json looks like this.
package.json
"scripts": {
"cluster": "cd cluster && PORT=5000 ara run:cluster --config . /views.json",
"layout": "cd layout && PORT=8080 node . /bin/www",
"proxy": "cd proxy && HYPERNOVA_BATCH=http://localhost:5000/batch PORT=8000 ara run:proxy --config . /nova-proxy.json",
"search:dev": "cd search && PORT=3000 . /node_modules/webpack/bin/webpack.js --watch --mode development",
"product:dev": "cd product && PORT=3001 . /node_modules/webpack/bin/webpack.js --watch --mode development", "product:dev"
"dev": "concurrently -n cluster,layout,proxy,search,product \"npm run cluster\"\"npm run layout\"\"npm run proxy\"\"npm run search:dev\"\"npm run product:dev\"",
}
The steps to create the product are as follows. 1.
Create a Nova Proxy 1. Create a Nova Directive (Layout) 1. Create Nova Cluster
- create Nova Bindings (Hypernova)
To use the Ara-Framework, the following preparations must be made.
$ npm i -g ara-cli
Nova Proxy
Nova Proxy will proxy to Nova Directive, so write its host.
nova-proxy.json
{
"locations": [
{
"path": "/",.
"host": "http://localhost:8080",.
"modifyResponse": true
}
]
}
Nova Proxy also needs to specify a URL in the variable HYPERNOVA_BATCH
in order to query the Nova Cluster.
To run Nova Proxy, execute the following command.
$ HYPERNOVA_BATCH=http://localhost:5000/batch PORT=8000 ara run:proxy --config . /nova-proxy.json
Nova Directive (Layout)
Nova Directvie uses hypernova-handlebars-directive
.
This can be used with the Node.js handlebars template engine (hbs).
It generates Express templates.
$ npx express-generator -v hbs layout
Without going into too much detail, create the following HTML file (hbs): $ npx express-generator -v hbs layout
- For more information https://ara-framework.github.io/website/docs/render-on-page
layout/index.hbs
<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>
{{>nova name="Search" data-title=title }}
<script src="http://localhost:3000/public/client.js"></script>
<script src="http://localhost:3001/public/client.js"></script>
{{>nova}}
is the Hypernova placeholder hypernova-handlebars-directive
.
name is the name of the Nova Bindings (explained later) and data-* is the data to be passed to the Nova Bindings.
The reason client.js is loaded in the script is to realise the CSR.
The move is the same as when running Express, and is as follows.
$ PORT=8080 node . /bin/www.
Nova Cluster
Nova Cluster manages Nova Bindings.
views.json
{
"Search": {
"server": "http://localhost:3000/batch"
},
"Product": {
"server": "http://localhost:3001/batch"
}
}
Search and Product are the names of the Nova Bindings you will create later; server is the URL where Nova Bindings is running.
To run Nova Cluster, execute the following command.
$ PORT=5000 ara run:cluster --config . /views.json
Nova Bindings
To create Nova Bindings, run the following command.
$ ara new:nova search -t react
$ ara new:nova product -t vue
From there, here is a slightly modified version from the auto-generated directory
search/Search.jsx.
import React, { Component } from 'react'
import { Nova } from 'nova-react-bridge'
class Search extends Component {
render() {
<div>
<div>Search Components!</div>
<table>
<tr>
{['🐙', '🐳', '🐊', '🐍', '🐷', '🐶', '🐯'].map((emoji, key) => {
return <td key={key}>
<Nova
name="Product"
data={{title: emoji}}/>
</td>
})}
</tr>
</table>
</div>
}
}
Not described so far, but we use nova-react-bridge
, which is Nova Bridge.
It is similar to Nova Directive, but the available files are compatible with JS frameworks such as React and Vue.js.
This means that it can also be used for Nuxt.js, Next.js and Gatsby.js.
This sample Nova Bridge works with CSRs; to work with SSRs, you will (probably) need to insert a Nova Proxy.
product/Product.vue
<template>
<div>{{title}}</div>
</template>
<script>
export default {
props: ['title']
}
</script>
To get these working in Nova Bindings, run the following command.
# search.
$ PORT=3000 . /node_modules/webpack/bin/webpack.js --watch --mode development
# product
$ PORT=3001 . /node_modules/webpack/bin/webpack.js --watch --mode development
Checking that it works
We need to run everything we have introduced so far concurrently.
So use concurrently
.
$ concurrently -n cluster,layout,proxy,search,product "npm run cluster" "npm run layout" "npm run proxy" "npm run search:dev" "npm run product:dev"
As an action, the image will look like this
Finally.
Again, the Ara-Framework allows a clear separation between data construction (Nova Directive) and rendering (Nova Bindings). Also, the rendering parts can be independent of each other. For the parts of the API not introduced here, you need to think about who will manage them and how.
However, the CSR javascript used in Nova Bindings contains duplicate code, which increases browser load times. This is where the Federation feature, available since webpack 5, comes in as a solution.
This was an introduction to the Ara-Framework!
Share
Related tags
- I read 'Micro Frontends'
- Defining Fragments Composed in Micro Frontends as Web Components and Sharing them with Module Federation
- Micro Frontends on the Client Side (ES Module)
- Memo Micro Frontends
- Building Micro Frontends with Cloudflare Workers (Edge Worker)
- Everything you need to know about Micro Frontends
- Micro Frontends with Zalando tailor (LitElement & etcetera)
- Everything I Learned About Micro Frontends
- Created an App to Consistently Record and Visualize Data in a Free Format
- Developing "Bochi-Bochi", an App to Easily Find Cheap Ingredients
- What I Learned from Refreshing My Blog Page with Qwik
- Introducing AI Ghostwriter - A Tool to Improve Writing Efficiency
- Development of Stable Diffusion API
- Defining Fragments Composed in Micro Frontends as Web Components and Sharing them with Module Federation
- Created OEmbed and OGP WebComponents for use on my blog site
- Things I Learned from Developing Chrome Extensions (Manifest V3)
- If you're writing in Markdown, Rocket, an SSG that uses WebComponents, is recommended!
- Refreshing Silverbirder's Portfolio Page (v2)
- I Made an API That Only Returns Google Account Images
- Building a TikTok Scraping Infrastructure on GCP and the Challenges Faced
- Micro Frontends on the Client Side (ES Module)
- Micro Frontends with Zalando tailor (LitElement & etcetera)
- Created a GAS Library, zoom-meeting-creator, to Automatically Generate Zoom Meetings
- Introducing a Tool for Bulk Updating Account Images and What I Learned
- Cotlin is a Tool for Collecting Links on Twitter, Discover Presentations from Around the World
- I tried creating rMinc, a service that registers GMail to GCalendar
- I Tried Making a One-Frame Comic Search Service Tiqav2 (Algolia + Cloudinary + Google Cloud Vision API)