Microfrontends with Ragu
Tags: webdev, microfrontends, react, productivity
Published: 2020-11-03 20:50:15

Recently I published a short video on my youtube channel with a brief explanation about microfrontends. In this article, I'll share some thoughts about why to use microfrontends and how easy is it to implement using Ragu.

{% youtube XkV7eRLa32Q %}

## Why to use microfrontends?

Nowadays, micro-services are popular which helps teams to reach independence at the back-end. Even enterprises that use the microservice model are still tired in a front-end monolith.

To have a practical understanding of what the microfrontend architecture looks like, let's use an e-commerce as an example.

![E-commerce basic architecture](https://dev-to-uploads.s3.amazonaws.com/i/tcin8x8w7117ds8de3x3.png)

An E-commerce is a complex application with multiple domains and disciplines. It is hard to imagine only one team handling all this complexity over time.

## Approaches to handle a Front-end monolith

I've seen mainly two approaches to be used to handle front-end monoliths. The first one is about having a front-end team. The main issue with this approach is that unless your team is a product API team, back-end teams could not deliver value by themselves. 

![team organization with a front-end team](https://dev-to-uploads.s3.amazonaws.com/i/5glz3fdo33wsanc0aho9.png)
 
Another common approach is about having a shared front-end monolith. Usually, companies that use this approach also have an "opensource enterprise" mindset where teams approve PRs of each other.

![team organization without a front-end team](https://dev-to-uploads.s3.amazonaws.com/i/0o4cjromcp9nz2wfkxy3.png)

In this approach, teams can have more autonomy and can deliver value without external dependencies. However, they are still facing some pain points of sharing a large and complex codebase. They may face a lack of ownership, lack of standards over the codebase, merge conflicts, painful maker decision processes as it involves too many people, etc.

## The microfrontend approach

At the back-end, companies have been using microservices for years to address most of these pain points. What if we extend the microservices ideas into the front-end?

![Microfrontend approach one micro-service and one microfrontend by domain](https://dev-to-uploads.s3.amazonaws.com/i/qcx4uqzcyr97hbx80phe.png)
 
Then teams could have full autonomy in their delivery process.

## The Ragu Architecture

Ragu is organized into two main applications: `ragu-server` and `ragu-client`. Ragu Server exposes components as microfrontends just as many restful microservices does.

Each microfrontend has its own resource URL that returns the microfrontend HTML and other properties used by Ragu Client to resolve the component.

![Ragu Server](https://dev-to-uploads.s3.amazonaws.com/i/mfnv1jn2wqx6yl7sr15g.png)

Ragu client basically receives the microfrontend resource URL and renders the microfrontend. 

![Ragu Client](https://dev-to-uploads.s3.amazonaws.com/i/eddfmmo3zglbb4v8lge7.png)

To compose the application, we will have an `application entrypoint` that renders microfrontends using a `ragu client`. Also, we can have as many `ragu servers` as we need. It is recommended to have one `ragu server` per domain.

![Ragu architecture](https://dev-to-uploads.s3.amazonaws.com/i/2unohugifti4fkkitp3z.png)

## Ragu code example

Ragu is technology agnostic. You can use Ragu with your favorite framework. In this example, we will be using React.

```bash
npm install ragu-server
```

Ragu comes with some scripts to build the project, to start the production and the development server. All you need to do is to provide a `config` file for these scripts into your `package.json`.

```json
{
  "scripts": {
    "ragu:build": "ragu-server build ragu-config.js",
    "ragu:start": "ragu-server run ragu-config.js",
    "ragu:dev": "ragu-server dev ragu-config.js"
  }
}
```

### The config file

To create the config file, you can use the `ragu-react-server-adapter` library.

```bash
npm install ragu-react-server-adapter
```

The `ragu-config.js` will looks like it:

```javascript
const {createReactRaguServerConfig} = require('ragu-react-server-adapter/config');

module.exports = createReactRaguServerConfig({
  compiler: {
    assetsPrefix: 'http://localhost:3100/component-assets/'
  },
  components: {
    namePrefix: 'my_project_name_'
  }
});
```

For more information about the React `ragu-config.js` file, check the documentation: https://ragu-framework.github.io/#!/ragu-react-server-adapter

**Fun fact**: The documentation is actually a microfrontend. It is hosted by Heroku's free server so it may take a while to load.

### Ragu Server: Exposing a component

Ragu Server has a filesystem-based routing system, it means that the component URL will match with the name of the component directory. All components live inside the `ragu-components` directory.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/106218m4zqgjwdworkhg.png)

To expose a React Component as Microfrontend, you just need to export a function that returns a component. `<project_root>/ragu-components/hello-world/index.jsx`:

```jsx
import React from 'react';

const HelloComponent = () => (<div>
    <h2>Hello, World</h2>
</div>);

export default () => <HelloComponent />
```

One of the main advantages of Ragu is that it is a thin layer in your application. You don't need to change your entire application to make it works. Actually, you export your component as a microfrontend as same as you use it.

Check the repository for this and more examples:

{% github carlosmaniero/ragu-server-react-example %}

### Ragu Client: Using a Microfrontend

Your application entrypoint can be anything: A React SPA, a VueJS application, a node application that renders HTML, or even a single HTML page. You don't need to learn a whole new framework.

For React, there is a client to make the integration even more straightforward.

```bash
npm install ragu-client-react
```

```jsx
import { RaguComponent } from "ragu-client-react";

function App() {
  return (<div>
    <h1>My Drawer App</h1>
    
    <RaguComponent src="http://localhost:3100/components/hello-world"></RaguComponent>
  </div>);
}

export default App;
```

Check the full example at:

{% github carlosmaniero/ragu-client-react-example %}


## Why to use?

Because to use a microfrontend it is as simple as use an iframe.

To expose a microfrontend it is just like to use storybook

Server side rendering, for a better user experience and to improve the visibility of your application at search engines.

You can have teams focused on the value stream with independent deployment. The integration is just an URL. There is no artifact integration.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0rc0ksbremvy065xliev.png)

Give it a try [https://ragu-framework.github.io](https://ragu-framework.github.io)