Table of Contents
Pese a ser muy usado hoy en día, módulos Webpack siguen siendo una caja negra para muchos developers que se limitan a usar una configuración ya existente sin saber cómo funciona realmente.
Debido a esto desgranaremos un poco algunas de sus partes para ayudar a entender su funcionamiento y así poder optimizar nuestra configuración de Módulos Webpack según nuestras necesidades.
Para ello empezaremos explicando algunos Módulos Webpack y veremos cómo nos pueden ayudar.
Módulos Webpack
Módulos
Usando los modules Webpack podemos dividir nuestro código en diferentes ficheros, de forma que cada fichero tenga una sola responsabilidad, lo que hará nuestro código mucho más entendible y fácil de testear.
Para poder llevarlo a cabo haremos uso de los imports de ES6 ya que nos permiten importar y exportar nuestras dependencias para usarlas en otros módulos. A pesar de ser muy útil, el uso de imports sin control puede generar problemas de performance al importar módulos muy pesados o importar módulos que no son necesarios hasta que el usuario interactúa con determinadas secciones de la aplicación, por lo que no deberíamos llamarlos desde un inicio. Para solucionar ambos problemas hablaremos de Tree shaking y Dynamic imports.
Tree Shaking
El concepto de Tree Shaking es muy fácil de entender. Webpack analiza nuestros módulos en busca de imports y exports y cuando encuentra algún módulo que importa o exporta contenido y no es usado, lo descarta para evitar tener código muerto.
Aquí podemos ver un ejemplo:
employee.js
export const firstName = 'Arnau';
export const lastName = 'Silvestre Dulcet';
export const position = 'Frontend';
export const company = 'Apiumhub';
Index.js
import { firstName, lastName, company, position } from './employee';
console.log(firstName, lastName, company, position);
Al ejecutar el siguiente código usando todas las constantes que hemos importado de employee vemos que para el fichero index.js (donde realizamos nuestros imports) genera un bundle de 122 bytes. En este caso Tree shaking no está actuando, ya que como usamos todos nuestros imports, no hay nada a descartar.
Sin embargo, en el siguiente caso:
import { firstName, lastName, company, position } from './employee';
console.log(firstName, company);
Solamente usamos firstName y company, y pese a que también importamos lastName y position, no los estamos usando en nuestro código, por lo que Webpack los descarta.
Gracias a eso podemos reducir el tamaño de nuestro bundle. Pese a que en nuestro ejemplo solo resulta en una diferencia de 20 bytes, hay que remarcar que es un ejemplo muy sencillo, pero en un proyecto puede resultar en una enorme diferencia.
Para poder activar esta funcionalidad añadiremos el campo sideEffects: false en el primer nivel de nuestro package.json, indicando que nuestro proyecto no contiene side effects y permitiendo así el Tree shaking.
{
"name": "projectName",
"version": "0.0.0",
"license": "MIT",
"sideEffects": false
}
Como dice la propia documentación de Webpack: Un side effect se define como el código que realiza alguna acción especial al ser importado, a parte de definir sus exports.
Dynamic imports
El uso de dynamic imports nos permite importar un módulo en cualquier parte de nuestro fichero, lo que nos permite importar contenido bajo ciertas casuísticas, disminuyendo así el tiempo de carga de nuestras páginas. Esto es especialmente útil si trabajamos con módulos muy pesados y solo necesitamos uno de ellos para poder navegar.
No necesitamos ninguna configuración específica de Webpack,a partir de la v2, para poder usar dynamic imports.
setTimeout(importModule(), 3000);
function importModule() {
import('./employee').then(myModule => {
console.log(myModule);
});
}
En el ejemplo anterior la variable myModule contiene la información de nuestro módulo (variables, métodos…)
Los dynamics imports suelen usarse para cargar los diferentes contenidos de las páginas según el estado de nuestra navegación. ¿Por qué debería cargar el contenido de la sección About o Contacto de mi página si solamente estoy mostrando la Home?
Tree Shaking y Dynamic imports
Una vez presentados ambos vamos a hablar de los problemas de compatibilidad en el momento de usarlos conjuntamente.
if(admin == true) { import('./admin').then(myModule => { console.log(myModule); }); }
Y un import estático:
import {person} from ‘./person.js’;
Es que Webpack no puede saber a priori si el dynamic import va a llegar a ser usado en algún momento, por lo que en esos casos no puede aplicar Tree Shaking y no puede descartar dynamic imports que no vayan a ser usados jamás.
Teniendo esto en mente en el momento de preparar nuestra configuración de Webpack, debemos pensar qué queremos conseguir y si queremos usar uno u otro, o ambos. Debemos pensar la estrategia que vamos a seguir, para poder usarlos conjuntamente y conseguir que ambas funcionalidades se complementen en lugar de colisionar.
Suscríbete a nuestro newsletter para estar al día de módulos Webpack!
Si este artículo sobre módulos webpack te gustó, te puede interesar:
Simular respuestas del servidor con Nodejs
Principio de responsabilidad única
Arquitectura de microservicios
F-bound en Scala: traits genéricos con higher-kinded types
Scala Generics I : Clases genéricas y Type bounds