Aprende Webpack desde cero

Webpack tree shaking

  • Otras de las características más potentes de Webpack (llamada tree shaking) permite eliminar el código que no estamos utilizando en nuestra aplicación, reduciendo el tamaño de nuestro bundle y mejorando la experiencia de usuario.
  • Si imaginamos nuestro proyecto como un árbol, las hojas verdes representan el código, utilidades y partes de librerías que sí usas. Las hojas marrones y a punto de caerse representan todo no tiene utilidad pero está siendo incluido en el proyecto. Para deshacerte de esas hojas debes sacudir el árbol, haciendo que se caigan.
  • Tree shaking se basa en el uso de módulos ES2015: import y export ya que la naturaleza dinámica de los módulos CommonJS (require) no permiten hacerlo, así que ten en cuenta que necesitas usar este tipo de módulos en tu aplicación y en las librerías que utilices.
  • Si utilizas Babel, recuerda indicar "modules": false para que no transpile los módulos de tu aplicación a CommonJS.
  • Otro aspecto importante es que tree shaking sólo funciona en modo producción porque necesita que el código sea minificado. Tenlo en cuenta.
  • Aunque Webpack pueden adivinar "out of the box" qué codigo puede ser eliminado en algunas ocasiones, generalmente debemos indicarle qué partes de nuestra aplicación son puras, es decir que no tiene efectos secundarios como código JavaScript que inicializa globalmente algún servicio o los estilos generales de nuestra aplicación.
  • Si Webpack elimina código con ramificaciones y efectos secundarios en nuestra aplicación, esta no funcionará bien.
  • Basta de teoría. El primer paso para indicar a Webpack qué es pure y cual include side effects es utilizar la propiedad usedExports dentro del objeto optimization. Con esto Webpack identificará el código que crea no estamos usando y lo marcará para eliminar en el proceso de compilación. Vamos a ponerlo a prueba.
  • Primero vamos a crear para esta lección una tarea que active el modo desarrollo al compilar (sin servidor) añadiendo "build:dev": "webpack --mode=development" a nuestro package.json.
  • Ahora creemos un nuevo archivo JavaScript que exporta dos funciones muy sencillas.
export default function sayHi() {
  console.log("Hi!!!");
}

export function sayBye() {
  console.log("Bye!!!");
}
  • Si importamos el archivo en nuestro main.js y lanzamos una compilación dev para examinarla.
import sayHi, { sayBye } from "./utils.js";
  • Veras que aunque no hemos hecho uso de ninguna de ellas, se encuentran en el bundle final.
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return sayHi; });
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sayBye", function() { return sayBye; });
function sayHi() {
  console.log("Hi!!!");
}
function sayBye() {
  console.log("Bye!!!");
}
/***/ })
  • Si hacemos uso de sayHi y compilamos de nuevo, no hay diferencia. Ambas se incluyen en el bundle final.
  • Vamos a añadir usedExports a nuestra configuración y compilamos, verás que aunque esta vez no estamos importando sayBye, sigue presente en el bundle.
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return sayHi; });
/* unused harmony export sayBye */
function sayHi() {
  console.log("Hi!!!");
}
function sayBye() {
  console.log("Bye!!!");
}
/***/ })
  • Como indica en la documentación, si todas las aplicaciones y librerías usasen módulos ESM no haría falta indicarle a Webpack la "pureza" de nuestro código. Como no es el caso, debemos añadir la propiedad sideEffects en nuestro package.json.
  • Si indicamos un valor false, estamos diciendo que todo nuestro código es puro y, por lo tanto, susceptible de tree shaking. Hagámoslo y lancemos un proceso de compilación.
{
  "name": "webpack-desde-cero",
  "sideEffects": false,
	...
}
  • Para encontrarte que todo sigue igual. Esto se debe a que para que Webpack pueda terminar de "sacudir" esas hojas a punto de caerse, debemos utilizar el modo producción. Lancemos un npm run build y examinemos el bundle sólo encontrarás referencias a sayHi. En fecto, la función sayBye ha sido eliminada.
  • Si eliminamos el uso de sayHi y dejamos sólo la sentencia de import verás que en el bundle final no hay ninguna referencia.
  • Antes de finalizar quizás te estés preguntando qué ocurre si partes de tu aplicación no son "puras". Por ejemplo la típica hoja de estilos global que afecta a toda la aplicación. En nuestro ejemplo no tenemos porque usamos Vue Loader y single file components, pero sería tan sencillo como indicarle a sideEffects una o varias rutas donde se encuentran esas dependencias impuras.
{
  "name": "webpack-desde-cero",
  "sideEffects": [
	  "./src/scss/global.scss",
	  "./src/utils/global.js"
	 ]
...
}
  • Por último, ¿qué pasa con el código de terceros?. La mayoría de librerías (o al menos las más populares) vienen listas para ser utilizadas con tree shaking casi de forma automática.
  • Por ejemplo la archiconocida Lodash permite importar las funciones que necesitas en lugar de toda la librería.
  • Lo mismo ocurre con Highligh.js, la cual se utiliza en Escuela Vue. Por defecto incorpora un montón de sintaxis, pero si se incorpora sólo lo que vamos a utilizar la diferencia es dramática, te lo aseguro.

No te pierdas ninguna novedad

Escuela Vue en Twitter

Participa en la Comunidad Escuela Vue

Comunidad Escuela Vue