Microfrontend — Build simple e-commerce with Piral Framework
Github: https://github.com/kanin-kearpimy/Piral-Microfrontend-React-and-Vue
Introduction
Nowadays software applications are required a fast development process with less complexity. Since Monolith to Microservice mostly focuses on the Backend aspect. How can we ensure more efficient development with a larger application? That is where Microfrontend comes to fit it.
Microfrontend is an architectural style of software development. It can make significant benefit on those below:
- Incremental Upgrade: New code is able to build without affecting to old one.
- Simple, Decoupled Codebases: Whole large codebases into small chunks (team).
- Independent Development: Each team can develop without relying heavily on others.
- Autonomous Teams: Full ownership of the team (Vertical-oriented development).
Piral Framework
Piral is a Javascript framework focused on Microfrontend.
Piral is composed of 3 main components.
- App Shell: Comprehensive structure centralizes all of Pilet (team) in one place.
- Pilet: Feature module owns my independent team.
- Feed Service: Command center to control of App Shell and Pilet version, Assets, Rules, and etc. You can think of it as a webserver
Application Architecture
In this project, we will build up a mini-eCommerce with a product list and cart. There are 3 teams;
- APP-SHELL team: handle centralizing stuffs-relate such as share-layout, authentication.
- Pilet-1 (React) team: create product list, product card with detail. Integrating buy-button from Pilet-2 team.
- Pilet-2 (Vue) team: build up cart and buy button to collect request from user-buying
Hand-on
Pre-install:
- Node Package Management (NPM)
- NodeJS
- Register to Piral Cloud for feed-service (https://www.piral.cloud/)
Installation
To install Piral please following below in your terminal/command prompt
// install piral as global package
npm i piral-cli -g// check version and status
piral --version
Create APP-SHELL team
piral new --target app-shell
After installing complete, navigate terminal to app-shell folder and run up server.
cd app-shell/// run up app-shell team
piral debug
Then go to http://localhost:1234 in your web browser.
Go to /src/layout.tsx in your app-shell folder and change code as down below. We are customizing the Layout (main container) and Menu for our mini-eCommerce
Go to http://localhost:1234 to see update
Piral has build default layout for app-shell in “layout.tsx”. Before we go, let open “index.tsx” and modify your “feedUrl” to be current feed following your “Piral Cloud”. We’ll use it as Feed-Service of whole project.
Please check https://docs.piral.io/guidelines/tutorials/03-publishing-pilets to create your feed-service in Piral cloud
const feedUrl = <your feed-service url from your piral cloud>;
Right now, we are all set. We have to build up an emulator of app-shell for Pilet creation. Run build script below. (Make sure you kill Piral debug process if you use same terminal)
piral build
There will be /dist appearing in app-shell folder.
Create PILET-1 (React) team
Now navigate back one level from app-shell folder and create pilet-1 team.
cd ..
pilet new app-shell/dist/emulator/app-shell-1.0.0.tgz --target pilet-1
It will be another folder name “pilet-1” appearing. navigating into it and run up a server for our Pilet-1
cd pilet-1// run up debug
pilet debug
Result
Pilet-1 will handle overview of product such as pull product data (mock), design product card.
Let create new file “ProductPage.tsx” in /src folder. This will handle Produc page and collect ProductCard as well. by receiving product data from index.tsx to display.
Create another file name “ProductCard.tsx” in /src folder to handle product detail.
If you noticed, we pass “buyBtn” from parent because it should be “called from another team”.
Let get back to /src/index.tsx and modify code following
If you noticed in “setup()” function which is the main function of Pilet. there are “registerTile()” which mean inserting any component into “APP-SHELL main layout”. Following our code. We’re inserting “<ProductPage />” into our “APP-SHELL”
Right now the http://localhost:1234/ should be like.
We have a couple of simple card with a product detail. But “buy-button” is not displayed! Stay tuned we are going to create it right away.
Upgrade app-shell for Vue compile.
Piral support react-typescript as main recommended framework. To use other framework like Vue. We have to convert vue to complied js file and loaded to vue. We will use installable package name piral-vue.
// navigate to app-shell folder
cd app-shell// pre-install for vue
npm install vue// install package
npm install piral-vue
Then import index.tsx in app-shell folder.
We imported piral-vue convertor and exposed public API in plugins[]. This is how app-shell control centralization for all pilets.
Then upgrade version of app-shell and build piral again.
// update npm package version
npm version patch// build piral
piral build
Before we go. After we create pilet-2. Our system of Microfrontend would look like:
Above picture describe Pilet-1 was created with app-shell version 1.0.0 when app-shell updated the version to 1.0.1. Pilet-2 can utilize full lastest centralized package (Vue converter). But Pilet-1 (if no upgrade) couldn’t use new package (Vue converter). By the way, Pilet-1 is still working because Pilet-1 and Pilet-2 are independently developed.
Create PILET-2 (Vue) team
Navigating back one level from app-shell folder and creating pilet-2 team.
cd ..
pilet new app-shell/dist/emulator/app-shell-1.0.1.tgz --target pilet-2// navigating to pilet-2 folder
cd pilet-2// install vue, vue-loader, and vue-template-compiler
npm install vue vue-loader vue-template-compiler// run up debug to check
pilet debug
Because Vue need vue-loader to compile. We have to inject vue-loader in webpack of pilet-2 as well. Creating webpack.config.js in root directory of Pilet-2
you can go to http://localhost:1234 to check.
Let create new file name: BuyButton.vue to be buy button for pilet-1 (react) card
This button will be exposed universally and used by Pilet-1 team. We are going to universally register extension and share state in our Pilet-2 component.
Modify index.tsx
There are 2 new features of Piral here:
- share state between Pilets
- share component between Pilet.
If we would like to share data within Pilets. We have to register “data” by setData(<name>, <data>). Following the above code. We create cart as an array to collect products. Next, we create addToCart() function to add product data to current cart. BuyButton will receive addToCart() function to use in Product Card.
Lastly, we register universal component for BuyButton by registerExtension(). Name it buy-button.
Pilet-2 is also handling the cart page to display products in the cart. Let create another file Cart.vue.
and modify index.tsx as below:
line 26: register new menu with Link (/cart) to Cart Page
line 27: register new page in Microfrontend for /cart
line 29–34: We define watcher for ‘cart’ shared variable. If it change we will update number of products in Cart.
Now we are completed almost everything. We lastly have to publish all Pilets to Feed-Service.
Publish Pilet-1 (React)
// navigate to pilet-1
cd pilet-1// publish
pilet publish --fresh --api-key <key from piral cloud> --url <feed-service url from piral cloud>
Publish Pilet-2 (Vue)
// navigate to pilet-2
cd pilet-2// publish
pilet publish --fresh --api-key <key from piral cloud> --url <feed-service url from piral cloud>
Then go back to app-shell folder and run debug.
piral debug
The result will display as below:
Lesson Learn:
- If 2 or more teams are isolated. The team is growing so big. Microfrontend can help manage the engineering development process.
- If a team is small and partial (less) isolated, Monolith probably plays more important.
Github: https://github.com/kanin-kearpimy/Piral-Microfrontend-React-and-Vue
References:
- https://portal.piral.cloud/
- https://docs.piral.io/guidelines/tutorials/12-sharing-between-pilets
- https://docs.piral.io/guidelines/tutorials/14-converters
- https://martinfowler.com/articles/micro-frontends.html
Credit picture: