Angular libraries y Storybook

Generación una librería de componentes lista para publicar en paquetes

Angular libraries y Storybook

You can read this article also in English.

Las guías de estilos han existido desde hace años, pero desde hace no tanto, diseñadores y desarrolladores se han puesto de acuerdo para trabajar en conjunto en una idea que está dinamizando y facilitando el uso de UIs a lo largo de los productos de grandes compañías. Estoy hablando de los sistemas de diseño y su consecuencia en el desarrollo de sofware: las librerías de componentes.

En este post vamos a crear una aplicación de Angular con Angular Libraries y Storybook, lista para publicar un sistema de diseño como paquete. El resultado lo puedes ver en el siguiente repositorio.

Un sistema de diseño es un conjunto de componentes UI reusables que permiten a los equipos construir interfaces complejas y consistentes entre varios proyectos. A su vez pueden contener información sobre su uso, cómo construir dichas interfaces, o cualquier información relevante para su implementación o instalación. Las ventajas de los sistemas de diseño respecto a las antiguas prácticas son su escalabilidad, coherencia y solidez, por lo que se han convertido en la piedra angular de las grandes compañías y grandes proyectos en sus aplicaciones.

design-system-overview.jpg

Fuente: Storybook

Con esta situación y este nuevo paradigma surgía la necesidad de tener una herramienta que catalice ese conocimiento entre diseñadores y desarrolladores, genere una documentación útil para ambos y además facilite el consumo de esos componentes por parte de los proyectos que quieran usar ese sistema de diseño. Y Storybook llegó al rescate.

¿Qué es Storybook?

Storybook es una herramienta para construir componentes UI y páginas de manera aislada, generando documentación, y posibilitando tanto desarrollo como el testing de componentes. Permite la visualización de los componentes de una manera organizada, interactuar con ellos y testearlos como si se encontraran desplegados en una aplicación real. Esta herramienta es capaz de integrarse con múltiples frameworks como React, Vue.js, Angular...

storybook-dashboard.png

Fuente: Storybook

También puede generar una página estática con toda la documentación referida a esos componentes, información extra, para que sirva de referencia a los desarrolladores del proyecto. En fin, en 3 años se ha convertido en el estandar para este tipo de proyectos por su utilidad y su potencia. Podemos ver ejemplos de completas librerías de componentes, como la de Carbon Components, The Guardian o Shopify Polaris

Storybook cobra especial importancia si se le suma la idea de poder publicar paquetes con esos componentes, de manera aislada, para poder ser consumidos por cualquier aplicación que desee.

En un post anterior hablamos de cómo publicar componentes de Angular utilizando Angular Libraries. Mediante el uso de Storybook, se puede mantener el desarrollo, visualización, y testing de componentes de forma aislada y a su vez publicar los paquetes para que se pueden generar múltiples aplicaciones que usen dichos componentes.

Instalación

Antes de instalar Storybook es necesario crear un proyecto, en este caso de Angular, por lo que instalaremos la consola de Angular (si no se ha hecho previamente) y crearemos nuestro proyecto.

npm install -g @angular/cli
ng new angular-storybook -create-application=false

El modificador -create-application=false crea una aplicación de Angular “vacía”, lista para poder crear librerías. Procedemos a generar la librería.

cd angular-storybook
ng generate library design-system

El último comando genera una nueva carpeta projects donde se ubicará nuestra librería de componentes: una “aplicación” Angular dentro de otra aplicación Angular.

El siguiente paso es instalar Storybook en el proyecto:

npx sb init

Las versiones utilizadas tanto de Angular como de Storybook son las siguientes: Angular: ^13.1.0 - Storybook-angular: ^6.4.14

Esto hace que haya una serie de cambios necesarios para que todo funcione correctamente. En futuras versiones tanto de Angular como de Storybook esto debería quedar solucionado.

Primero es necesario realizar un fix en el fichero tsconfig.json de la carpeta .storybook.

// From
"extends": "",
// To
"extends": "../projects/design-system/tsconfig.lib.json"

// From
"include": ["../src/**/*", "../projects/**/*"],
// To
"include": ["../stories/**/*", "../src/**/*", "../projects/**/*"],

Al crear un proyecto Angular con el flag -create-application=false Storybook no es capaz de reconocer la ubicación de los componentes, de modo que hay que hacerlo manualmente. En el fichero angular.json de nuestro proyecto:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "design-system": {
      ...
    },
    "storybook": {
      "projectType": "application",
      "root": "stories",
      "sourceRoot": "stories",
      "architect": {
        "build": {
          "options": {
            "tsConfig": "tsconfig.json",
            "styles": [],
            "scripts": []
          }
        }
      }
    }
  },
  "defaultProject": "design-system"
}

Es importante que tanto la versión de @angular como la de @angular-devkit/build-angular sea como mínimo la 13.1.3, ya que la versión 13.1.2 genera un error de building al ejecutar Storybook.

Desarrollo

Ya tenemos listo el proyecto para comenzar a trabajar, pero ya que tanto Angular como Storybook crea componentes y ficheros de prueba es necesario refactorizar algún fichero.

En la carpeta projects/design-system/src/lib eliminaremos todos los ficheros design-system menos el .module, ya que este será el que sirva para importar todos los componentes creados en nuestro sistema de diseño. A su vez crearemos una carpeta llamada components/button. Movemos el fichero button.component.ts y button.css que se encuentra en la carpeta stories a esta última carpeta creada, creando nuestra librería con la siguiente estructura:

Estructura de la librería

Estructura de la librería tras la refactorización

También es necesario modificar el fichero public-api.ts para eliminar las referencias a ficheros eliminados previamente:

/*
 * Public API Surface of design-system
 */

export * from "./lib/design-system.module";

Para terminar, modificamos las declaraciones e imports del fichero design-system.module.ts:

import { NgModule } from "@angular/core";
import ButtonComponent from "./components/button/button.component";

@NgModule({
  declarations: [ButtonComponent],
  imports: [],
  exports: [ButtonComponent],
})
export class DesignSystemModule {}

Para esto nos quedaremos solo con el componente Button y su story, eliminando los componentes header y page. El resultado de la carpeta stories es el siguiente:

Estructura del proyecto tras la refactorización

Estructura del proyecto tras la refactorización

Ya tenemos nuestro proyecto listo para generar y publicar nuestro sistema de diseño, por tanto, lo podemos visualizar al ejecutar npm run storybook y dirigirnos a la url http://localhost:6006/.

En este repositorio se pueden ver el proyecto terminado con todos los cambios descritos.

Final result

Conclusiones

Si bien la instalación de Storybook con Angular es un poco áspera para este tipo de arquitectura, ya que actualmente hay algún bug, es una solución idónea en la que merece la pena trabajar para el desarrollo de sistemas de diseño de una forma ordenada y con el plus de la publicación de paquetes de Angular Libraries.

Referencias

https://www.nngroup.com/articles/design-systems-101/

https://angular.io/cli

https://angular.io/guide/creating-libraries

https://storybook.js.org/docs/angular/get-started/install

https://dev.to/saulodias/angular-library-storybook-44ma

https://github.com/storybookjs/storybook/issues/17039

https://storybook.js.org/tutorials/design-systems-for-developers/react/en/introduction/

Photo by FORTYTWO on Unsplash