Webpack tree shaking
Introducción
Conceptos esenciales
Uso práctico
- 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
yexport
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 objetooptimization
. 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 nuestropackage.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óndev
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 importandosayBye
, 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 nuestropackage.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 asayHi
. En fecto, la funciónsayBye
ha sido eliminada. - Si eliminamos el uso de
sayHi
y dejamos sólo la sentencia deimport
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.
El primer headless CMS tanto para desarrolladores como para marketers. Pruébalo gratis.
¿Tienes alguna pregunta sobre esta lección de Aprende Webpack desde cero?
Resuelve todas tus dudas sobre Webpack en la Comunidad de Escuela Vue: un lugar donde participar, aprender y ayudar. ¡Te esperamos!.
Tras el registro (si no lo has hecho ya) serás redirigido/a al canal adecuado en la Comunidad.