Cómo usar Librerías JavaScript compartidas con Angular en Liferay

DISCLAIMER: This blog  post has Spanish and English version.

Cuando generamos algunos módulos NPM a partir de generator-liferay-js, deberías ver que el módulo (.jar) generado es un "poco pesado". En el caso del módulo Angular Liferay tiene más o menos 20 MB. Ahora, imagina que queremos trabajar con varios módulos de este tipo e instanciarlos más de uno por página. Esto nos traería algunos problemas:

  • Pérdida de performance: Se descargará ficheros JS para cada módulo (los de la dependencia) lo que implica un mayor tiempo de carga.
  • Posibles conflictos entre versiones: Si se utiliza versiones distintas de angular puede llegar a haber conflictos.
  • Mayor tiempo de build: Al tener que empaquetar el módulo con todas sus dependencias el tiempo de build es considerablemente alto.

Entonces, nos hacemos la pregunta, ¿cómo podemos solucionar estos problemas?. Una posible solución es el uso de “Paquetes compartido”, es decir, tener una biblioteca común de javascript en un contenedor como proveedor y consumirla desde los módulos angular. Si no la conocías, a continuación puedes ver como hacerlo paso a paso.

Requerido: Node, Yeoman y NPM instalados

  1. Primero, es necesario instalar generator-liferay-js a nível global, ejecutando el siguiente comando:

npm install -g generator-liferay-js

 

  2. Tras la instalación, dentro de tu "liferay-workspace/modules" o alguna otra carpeta de proyecto que estés utilizando, ejecuta el generador con:

yo liferay-js

 

  3. Elige el tipo "Shared Bundle" y completa el resto de la información necesaria:

  4. Abre el src/index.js y agregue después del init():

console.log('common-js-bundle is working as provider...'); 


  5. Ahora crea un proyecto angular, ejecutando el generador dentro de su "liferay-workspace/modules" o alguna otra carpeta de proyecto que estés utilizando

yo liferay-js 

 

  6. Elige el tipo "Angular Widget" y completa el resto de la información necesaria:

  7. Abre el package.json y copia todo dentro de “dependencies”. 

  8. Copia como “dependencies” en el package.json del módulo “Shared Bundle” creado anteriormente.

  9. Dentro del módulo del tipo “Shared Bundle” ejecuta el siguiente comando para instalar las librerías/dependencias añadidas.

npm install

 

  10. De vuelta al módulo “Angular Widget”, abre el fichero .npmbundlerrc ( a continuación la configuración necesaria)

     a. Excluye todas las dependencies declaradas dentro del módulo, eso nos garantiza que no será añadido a la hora de construir el .jar las dependencias declaradas en el package.json del proyecto, añadiendo lo siguiente: 

    "exclude":{
     "*":true
   },

     b. Importa todas las dependencias que necesite consumir del módulo “Shared Bundle". Lo podemos hacer a través de "config/import" + el nombre del proveedor. Debe quedar más o menos como el ejemplo abajo:

 "config":{

   "imports":{

    "common-js-bundle":{

    "@angular/animations": "10.2.2",

    "@angular/common": "10.2.2",

    "@angular/compiler": "10.2.2",

    "@angular/core": "10.2.2",

    "@angular/forms": "10.2.2",

    "@angular/platform-browser": "10.2.2",

    "@angular/platform-browser-dynamic": "10.2.2",

    "@angular/router": "10.2.2",

    "rxjs": "6.6.3",

    "tslib": "2.0.3",

    "zone.js": "0.10.3"

   }

  }

},

    c. Finalmente, si deseas acceder a index.js desde su proveedor (Shared Bundle project), solo necesitas agregarlo sin el namespace dentro del "import"

    "":{
      "common-js-bundle" : "^1.0.0"
    }

 

  • El código final del archivo .npmbundlerrc quedará más o menos así:


 

  11. Abre el src/polyfills.ts y importe el proveedor de librerías compartidas

     a. Esta importación, carga el fichero principal (index.js) del proveedor


 

  12. De vuelta a tu Proyecto Angular, elimina todo dentro de la carpeta build.

  13. Finalmente, desplegamos ambos proyectos: el consumidor (Angular Widget) y el proveedor (Shared Bundle). Para hacer eso, ejecute dentro de cada proyecto:

npm run deploy

 

                     ... Ahora ya deberías tener un modulo mucho mas ligero :) ...

 

Aquí  os dejo mi repo en Git con algunos ejemplos:  https://github.com/RoselaineMarquesMontero/liferay-workspace-shared-library/tree/main/modules