Pro Blog

Conflictos de nombre de fichero en módulos ES con Webpack

Conflictos de nombre de fichero en módulos ES con Webpack

TT;DR

Hace unos días compramos dos temas premium para React + Material-UI:

Para nuestro proyecto nos interesan unos pocos componentes de cada tema.

Normalmente diseñamos y maquetamos nuestros propios componentes.

Los temas comerciales suelen utilizar el gancho de la vistosidad como herramienta de venta.

Es habitual encontrar temas muy bien presentados pero que flojean en su implementación, lo cual hace difícil su adaptación a nuestro proyecto.

Tratándose de React esto es especialmente importante.

En este caso los temas se proveen en un fichero comprimido zip.

Cuando utilizamos librerías o temas comerciales de terceros empaquetadas en un fichero comprimido, es decir, no gestionadas con un sistema de control de versiones como git ni un gestor de paquetes como npm, nuestra prioridad es NO TOCAR. O tocar lo menos posible.

De este modo evitaremos sobreescribir cambios en futuras actualizaciones del tema.

Los componentes que encontramos en los temas de Creative Tim están implementados de forma bastante estándar dentro de una aplicación creada con Create React App:

Las referencias dentro de cada componente son relativas a la raíz del código fuente del componente (src/). Por ejemplo:

En material-kit-pro-react/src/components/Header/HeaderLinks.jsx vemos:

Y en material-dashboard-pro-react/src/components/Header/HeaderLinks.jsx vemos:

Y aquí empiezan los problemas.

¿Qué opciones tenemos?

Varias:

Vía código fuente (I):

No nos sirve, ya que dentro de src/ existen nombres de fichero iguales en ambos temas y los de uno reemplazarían a los del otro.

Vía código fuente (II):

Y desde nuestro proyecto haríamos referencia a los componentes de los temas así:

No nos sirve, ya que la referencias internas de los temas quedarían rotas.

Vía Webpack resolve.modules:

Y en webpack.config.js:

No nos sirve, porque la resolución de referencias se hace por prioridad decreciente y el import Button from "components/CustomButtons/Button.jsx"; de material-dashboard-pro-react resolvería a 3rdparty/material-kit-pro-react/src/components/CustomButtons/Button.jsx

Vía Webpack resolve.alias:

Y en webpack.config.js:

Y desde nuestro proyecto haríamos referencia a los componentes de los temas así:

Soluciona el caso anterior, pero no nos sirve, porque las referencias internas de cada tema quedarían rotas. import Button from "components/CustomButtons/Button.jsx"; no podría resolverse.

Vía Webpack resolve.alias + resolve.modules:

No nos sirve porque, aunque soluciona el caso anterior, las referencias internas de cada tema se resolverían por prioridad decreciente, lo que lleva al mismo problema que había con resolve.modules.

Solución

Para resumir, queremos lo siguiente:

  1. Desde nuestro proyecto, poder hacer referencia a ficheros concretos de cada uno de los temas.
  2. Dentro de cada tema tendrá prioridad la resolución en el directorio más cercano al fichero origen.
  3. Se podrá definir directorios prioritarios para poder reescribir referencias internas de los temas.

La única forma que hemos encontrado de conseguir esto ha sido mediante resolve.alias y un plugin para el motor de resolución, en resolve.plugin.

resolve.alias permite apuntar a un fichero específico de cada uno de los temas.

El plugin implementa la prioridad al directorio de reescritura o al directorio más cercano.

El plugin es el siguiente:

Y este es un ejemplo de uso en webpack.config.js:

En gist, aquí.

Puede descargarse así:

Leave a Reply

avatar
  Subscribe  
Notify of
Share This