In the previous blogs, we learned about the 4c’s and we also installed Entando on our local machines. In this blog, we are going to implement the 4c’s to create a very simple bundle and deploy it to our Entando Platform.
The question is, what is a Bundle?
An Entando Component Repository or ECR bundle is a package containing one or more components and a 'descriptor.yaml' file providing information about the bundle. The bundle is published on a Git registry and is shared with an Entando application using the EntandoDeBundle custom resource.
At first, we will create a widget that we would deploy to our Entando Platform. So currently, we are working as a creator. To do so, we’ll open up our favorite code editor/terminal, create a new folder and name it: product-listing
.
A little idea about what we’re going to build. We’ll build a simple React application that displays a few cards with some data on them, and this is what we define as our micro frontend (MFE). Then, we’ll run and build the React MFE. We next bundle up the entire MFE using ENT CLI and deploy it to the Entando Component Repository. Finally, we’ll install it in our App Builder, and drag and drop the cards widget (the one we created in React) to our Page!
Well, it might sound like a huge project, but it’s easy.
To begin, we will refer to this GitHub repository. This repository is an Entando project template that helps us to create a micro frontend, microservice, or both. Since we’ll focus on the micro frontend today, we’ll delete unnecessary files and folders from this project template, after we clone it. We’ll also rename the folders with respect to our project. And then copy everything inside the product-listing folder that we created previously. It should typically look like the structure below:
Inside the widgets-dir
folder, the cards-widget
folder is the React app that we create, as I’ve deleted the existing widget et-app
from the widgets-dir
folder. We can name it as per our own preference. I’ve created mine:
For the bundle_src
folder (inside product-listing
directory), we can see a descriptor.yaml
file. In there, we need to paste the following yaml code:
code: product-listing
description: Template for simple cards design
components:
widgets:
- ui/widgets/widgets-dir/cards-widget/cards-descriptor.yaml
This is a yaml file, through which we are telling the Entando Bundler that our widget is present inside the cards-widget
folder. And we are pointing it to the cards-descriptor.yaml
file that is present inside another bundle folder (one that we create inside our React app i.e inside cards-widget
directory). If we have more widgets inside the widgets-dir
folder, then we need to add them here too.
Now, I’m assuming you have followed the above folder structure and created a bundle folder with a cards.ftl
file and a cards-descriptor.yaml
file inside the cards-widget
folder. Hence, we go to the cards-widget > bundle > cards.ftl
file and add the following content:
<#assign wp=JspTaglibs["/aps-core"]>
<#-- entando_resource_injection_point -->
<#-- Don't add anything above this line. The build scripts will automatically link the compiled JS and CSS for you and add them above this line so that the widget can be loaded-->
<@wp.info key="currentLang" var="currentLangVar" />
<cards-widget locale="${currentLangVar}"/>
That’s it for this .ftl file. What typically happens here is, when we build our project using the ENT CLI command, all the build scripts and link tags appear here.
Under the same bundle directory, inside the cards-descriptor.yaml
file, we add the following code:
code: cards-section
titles:
en: Sample Cards Section Template
it: Sample Cards Section Template
group: free
customUiPath: cards.ftl
So far, we have filled all our descriptor files, ftl file, and have created our React app.
We keep the prepareBundle.sh
and prepareMicrofrontend.sh
files untouched, as they act like the engine of our machine!
Now that we are all done configuring all the files, we jump inside the cards-widget
folder and start designing our React app to display a set of cards. Inside the src
folder, we create a new file and name it cards.js
. We open up a terminal inside this directory and add a package to use bootstrap:
npm install react-bootstrap bootstrap@5.1.3
Now we add the following code to our cards.js
file:
import "bootstrap/dist/css/bootstrap.min.css";
import { Card, CardGroup } from "react-bootstrap";
export default function App() {
return (
<div>
<CardGroup>
<Card>
<Card.Body style={{ backgroundColor: "#F4ECF7" }}>
<Card.Title>Much Scalable</Card.Title>
<Card.Text>
Our product xyz is very scalable and has grown a lot in the past 2
years. More extra text here to explain.
</Card.Text>
</Card.Body>
<Card.Footer style={{ backgroundColor: "#D6EAF8" }}>
<small className="text-muted">Last updated 8 mins ago</small>
</Card.Footer>
</Card>
<Card>
<Card.Body style={{ backgroundColor: "#F4ECF7" }}>
<Card.Title>Very Fast</Card.Title>
<Card.Text>
Our product xyz is very fast and has proven itself a lot in the
past 2 years. More extra text here to explain.{" "}
</Card.Text>
</Card.Body>
<Card.Footer style={{ backgroundColor: "#D4EFDF" }}>
<small className="text-muted">Last updated 3 mins ago</small>
</Card.Footer>
</Card>
<Card>
<Card.Body style={{ backgroundColor: "#F4ECF7" }}>
<Card.Title>Free to use</Card.Title>
<Card.Text>
Our product xyz is absolutely free to use and is available to
download directly from our website. More extra text here to
explain.
</Card.Text>
</Card.Body>
<Card.Footer style={{ backgroundColor: "#FCF3CF" }}>
<small className="text-muted">Last updated 4 days ago</small>
</Card.Footer>
</Card>
</CardGroup>
</div>
);
}
And in our app.js
file, we replace the existing content with the following:
import "./App.css";
import Cards from "./cards";
function App() {
return (
<div className="App">
<Cards />
</div>
);
}
export default App;
Now that we have created our application, we need to wrap the entire React app into a custom element. Hence, we add a new file src/WidgetElement.js
with the following custom element:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
class WidgetElement extends HTMLElement {
connectedCallback() {
this.mountPoint = document.createElement("div");
this.appendChild(this.mountPoint);
ReactDOM.render(<App />, this.mountPoint);
}
}
customElements.define("cards-widget", WidgetElement);
export default WidgetElement;
Then, open src/index.js
and replace the entire file with these two lines:
import './index.css';
import './WidgetElement';
Lastly, we go to public/index.html
andreplace
<div id="root"></div>
with the custom element <cards-widget />
, like this:
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<cards-widget />
</body>
Perfect! Now, we need to build our React app before we build the entire bundle.
To do so, we run:
npm run build
We go to the root directory of the project. In our case, it is product-listing
, and set up the Project Directory:
To follow the steps below, we need to have our terminal open on the root directory. Then, we can run the following commands in the terminal.
- Prepare the bundle directory
cp -r bundle_src bundle
Here, the descriptor.yaml file gets copied to the bundle folder, where all our static resources will be created when we build the bundle going forward. So, in a way, we are preparing the bundle folder.
- Initialize the project:
ent prj init
- Initialize publication:
ent prj pbs-init
In this phase, we need an empty GitHub repository that we link here for our bundled code to be pushed to. This repository should be named like: product-listing-bundle
- Attach to Kubernetes for an Entando application via ent attach-kubeconfig config-file or similar.
Now, we publish the bundle to Entando App Builder:
- Build:
ent prj fe-build -a
(to just build the frontend, including changes frombundle_src
)
This is where our bundle is built, and remember i mentioned about the cards.ftl
file? That all the script and link tags are injected there? Well, this is the step where it happens. So right after you execute this step, you can go to the cards.ftl
file inside your bundle folder of the React app, and you’ll see those tags.
- Publish:
ent prj fe-push
(publish just the frontend) - Deploy (after connecting to k8s above):
ent prj deploy
At this point, we are pushing everything to the Entando Component Repository.
That’s all. Congratulations you just built a micro frontend using React, bundled it and deployed it.
Normally, here starts the Curation Phase. We are not using a Hub here. But, in general, when we have a Hub (The Hub is a central catalog where many curators and teams can share and collaborate on components or bundles. They can publish and manage versions, share metadata and communicate about features.), we publish and deploy a bundle to it. A curator validates it and ensures that components, business capabilities, and solutions are ready for composition, defining prerequisites and updating capabilities with the latest patches or upgrades. In our case, we imagine the Entando Component Repository to be the Hub and we are the curators for now.
Now it’s time we Compose the application from the Entando Component Repository.
At first, we login to our Entando App Builder:
We first see our dashboard, and from the dashboard, we navigate to the left button of our page, where we see “repository”. Click on it.
We can see our product-listing bundle here, and so we install it.
Then, we go to Pages from the left sidebar. And click on Management.
Here we add a page to our page tree, and design its layout to have some page frames, so that our widget(s) can fit. And then we save and design!
Here we see a list of widgets on the right sidebar, under “users”. We drag and drop the “Sample Cards Section Template” to any part of our page frame and click on publish. Then click on “view published page” and boom!
Congratulations again! You did it!
So, If people come to use this application, they would be Consumers of our application. But since this was just a demo to understand the workflow, we didn’t actually consume the application!
Well, that was just a little bit, so you understand the process. Like this, a team of many people can contribute to this same application. They can have widgets built in Angular, Vue, or Next.js and have them all here on a single web page. Isn’t that fascinating?
To check out if you’ve missed anything, do take a look at my uploaded source code at GitHub.
With this, we come to the end of our blog series, Getting started with Entando. You can see more blog posts on our website. We’re also building a community, where we can rapidly create a culture of Modular Applications along with you all. If that sounds interesting, do join us on our discord community! Thank you!
Top comments (0)