Module federation, ¿el futuro del micro frontend?
Tags: webdev, discuss, webpack, angular
Published: 2021-04-07 03:43:49

Estoy seguro que en alguna ocasión hemos escuchado de los micro servicios, una técnica bastante interesante en desarrollo backend que permite dividir tareas en sub tareas independientes que convivan entre si, a través de **module federation** y del **micro frontend** podemos lograr un concepto similar en el lado del cliente.

Si bien este concepto no es nuevo, la forma en como los frameworks de hoy en día se adaptan a esta técnica, permiten un desarrollo eficiente y granular. Pero, ¿en qué consiste exactamente una aplicación hecha con micro frontend?. Veamos la gráfica


![microfrontendchart](https://micro-frontends.org/ressources/diagrams/organisational/verticals-headline.png)

Como podemos ver consiste en dividir el frontend de un aplicación en pequeñas micro aplicaciones que cumplen un rol específico y se comunican entre si, de esta manera podemos trabajar de forma aislada en cada funcionalidad y hacer que convivan entre si, sin que exista esa dependencia. 

Algunos aspectos importantes de los micro frontend y reglas que se brindaron en la NGConf2020 (Conferencia mundial de Angular 2020):

1. Tecnologías independientes => cada micro app es trabajada con la tecnología que mejor se adapte a las funcionalidades de forma que el equipo es libre de decidir.

2. Código independiente => en la mayoría de casos y como buena práctica, se pide que cada aplicación conviva con si misma, es decir de no manejar estados o variables globales.

3. Establecer reglas de trabajo => se debe coordinar entre todos los equipos la forma en que se trabajara los estilos, los storage sea local storage, session storage, etc con el fin de manejar un estándar en todo el proyecto.

4. El DOM es la api => es preferible usar los **browser events** para la comunicación. Si es realmente necesario manejar una api general, tratar de mantenerlo lo más simple posible.

5. Apuntar al clean code, es una prioridad => si bien se trabaja en equipos separados, se debe manejar un estándar para que cualquier desarrollador front del proyecto pueda dar mantenimiento a cualquiera de las micro aplicaciones.

##Bien ahora, hablemos acerca de Module Federation:##

Con la llegada de Webpack5, tenemos la posibilidad de trabajar con micro frontend de forma sencilla, a través de un archivo de Webpack, podemos configurar en totalidad la salida y que archivos se estarán compartiendo de nuestros micro frontend. 

####Veamos el archivo de la aplicación principal en Angular...####

```javascript
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
    path.join(__dirname, '../../tsconfig.json'),
    ['session-lib']
);

module.exports = {
  output: {
    uniqueName: "shell"
  },
  optimization: {
    // Only needed to bypass a temporary bug
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({

        // For hosts (please adjust)
        remotes: {
          'admin': "admin@http://localhost:3000/remoteEntry.js"
        },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },
          "@angular/material/button": { singleton: true, strictVersion: true },
          "@angular/material/icon": { singleton: true, strictVersion: true },
          "@angular/material/toolbar": { singleton: true, strictVersion: true },
          "@angular/animations": { singleton: true, strictVersion: true },
          "@angular/cdk": { singleton: true, strictVersion: true },
          ...sharedMappings.getDescriptors()
        }

    }),
    sharedMappings.getPlugin(),
  ],
};

```

####Ahora conozcamos uno de los micro sitios anclados a esta micro app...####

```javascript
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
    path.join(__dirname, '../../tsconfig.json'),
    ['session-lib']
);

module.exports = {

  optimization: {
    runtimeChunk: false
  },
  plugins: [
    new ModuleFederationPlugin({

        // For remotes (please adjust)
        name: "admin",
        filename: "remoteEntry.js",
        exposes: {
          './Dashboard': './projects/remote/src/app/dashboard/dashboard.module.ts',
          './Contact': './projects/remote/src/app/contact/contact.module.ts',
        },

        shared: {
          "@angular/core": { singleton: true, strictVersion: true },
          "@angular/common": { singleton: true, strictVersion: true },
          "@angular/router": { singleton: true, strictVersion: true },
          "@angular/material/button": { singleton: true, strictVersion: true },
          "@angular/material/icon": { singleton: true, strictVersion: true },
          "@angular/material/toolbar": { singleton: true, strictVersion: true },
          "@angular/animations": { singleton: true, strictVersion: true },
          "@angular/cdk": { singleton: true, strictVersion: true },
          ...sharedMappings.getDescriptors()
        }

    }),
    sharedMappings.getPlugin(),
  ],
};

```

Como hemos podido ver, los archivos de configuración son bastante sencillos de configurar. Algo importante para resaltar es que son altamente escalables, el límite va a depender mucho frente a que aplicación estemos. Otro detalle a tener en cuenta es que si bien Webpack 5 ya fue lanzado, Angular 11 aún no tiene todo el soporte acerca del mismo, personalmente aún no lo usaría para producción, pero cada uno tiene su punto de vista y opinión 😎