Manual Webpack
Manual Webpack
Manual Webpack
http://desarrolloweb.com/manuales/manual-webpack.html Página 1 de 54
Manual de Webpack
Webpack comenzó como un proyecto del ecosistema de React, pero por su utilidad se ha
convertido en una herramienta usada de manera global en cualquier tipo de desarrollo
frontend. Los más representativos frameworks Javascript la usan internamente para facilitar el
flujo de desarrollo.
En este manual iremos publicando los artículos que te enseñen cómo usar Webpack en
proyectos de todo tipo y cómo sacarle el mayor partido a través de sus loaders y plugins.
http://desarrolloweb.com/manuales/manual-webpack.html Página 2 de 54
Manual de Webpack
Las siguientes personas han participado como autores escribiendo artículos de este manual.
Jonathan MirCha
http://desarrolloweb.com/manuales/manual-webpack.html Página 3 de 54
Manual de Webpack
En estos artículos encontrarás una guía esencial para empezar a usar Webpack. A partir de la
versión de Webpack 4 es muy sencillo comenzar a usar esta herramienta frontend. Conocerás
el uso de Webpack sin la necesidad de usar archivos de configuración y además estudiaremos
cómo configurar Webpack de manera básica a través de su archivo webpack.config.js
Webpack es una herramienta para empaquetado de archivos de sitios web, usada para el
desarrollo frontend. Se dedica a empaquetar en paquetes, comúnmente conocidos como
"bundles", todo el conjunto de ficheros que necesita un proyecto para funcionar, con todas sus
dependencias frontend.
Por ejemplo, Webpack es capaz de preparar un archivo Javascript con el código de todo tu
proyecto, dependencias incluidas, minimizado y transpilado. O un archivo con tu CSS, una vez
pasados los correspondientes preprocesadores, etc.
En este artículo pretendemos dar una aproximación muy práctica a los primeros pasos con
Webpack, sin embargo hay unos pocos conceptos que tenemos que explicar previamente, pues
tocan de lleno en la operativa que vamos a tener que realizar con la herramienta.
http://desarrolloweb.com/manuales/manual-webpack.html Página 4 de 54
Manual de Webpack
De momento y en resumen, esa es toda la teoría de salida que necesitamos comentar, así que
vamos directamente a la práctica. No obstante, antes de comenzar con la práctica más abajo en
este artículo, si quieres saber más sobre Webpack, los usos de la herramienta y dónde puedes
usarla, te recomendamos ver el siguiente vídeo.
Para trabajar con Webpack Necesitas una versión de NodeJS actual de NodeJS. Si no lo tienes
o hace mucho tiempo que no la actualizas, te conviene pasar por la página de NodeJS.
Nota: Aunque para usar Webpack no hace falta tener mucha experiencia desarrollando con
NodeJS, algo sí que debes saber. Puedes aprender en el Manual de NodeJS.
Luego, como sugerencia, puedes instalar Webpack de manera global, así estará disponible en
cualquier lugar de tu terminal, aunque luego puedes también deberías instalar de manera local
en el proyecto Webpack para que quede guardado como dependencia de desarrollo en el
package.json y para disponer de la versión adecuada para cada proyecto.
El paquete "webpack" es el propio Webpack y el paquete "webpack-cli" es el que tiene todos los
comandos de consola para realizar las operaciones con Webpack, que es necesario a partir de
Webpack 4. Insistimos: este paso es opcional y no sería suficiente en la muchos casos, pues la
buena práctica es disponer de tu copia de Webpack en local para cada proyecto, lo que te
permite tener una versión de Webpack específica. Si no lo haces así, puede ocurrir que la
http://desarrolloweb.com/manuales/manual-webpack.html Página 5 de 54
Manual de Webpack
configuración de Webpack con la que se inició el proyeto no sea compatible con la versión de
Webpack que tienes instalada en global.
Ahora crearemos una carpeta para nuestro proyecto, donde deseamos usar Webpack. O si ya
tienes un proyecto creado, simplemente te colocas en la carpeta raíz.
Ya en nuestro proyecto, en su carpeta raíz, tenemos que iniciarlo con npm, para que se puedan
ir grabando todas las dependencias que vamos a ir instalando. (Obviamente, si ya has hecho
este paso por tener dependencias de npm instaladas en el proyecto, no tendrás que repetirlo)
npm init
En el asistente de "npm init" podemos ir indicando todo lo que sea necesario, o pulsar "enter"
para que se vayan guardando los valores predeterminados.
Ahora, en este proyecto vamos a instalar como dependencia de desarrollo Webpack y su CLI.
Esto permitirá que podamos saber que en el proyecto se está usando Webpack y cualquier otro
desarrollador, al instalar las dependencias con npm, podrá instalarse Webpack en local. Otro
motivo de instalar Webpack en local es poder tener varias versiones distintas de la
herramienta, una por proyecto, de modo que sea más sencillo mantenerlos. Pues podría
ocurrir que la configuración de un proyecto con una versión de Webpack no sea compatible
con la versión que tengamos instalada en global.
Ejecutar Webpack
Ahora que tenemos instalado Webpack podemos comenzar a trabajar. Una de las novedades de
la versión 4 (en adelante) es que podemos ejecutar Webpack con literalmente "cero"
configuración.
Nota: esta era una de las demandas más habituales de los desarrolladores, evitar la
necesidad de configuración, a veces costosa de realizar, para comenzar a trabajar con
Webpack. A partir de la versión 4 los desarrolladores están trabajando para que así sea.
http://desarrolloweb.com/manuales/manual-webpack.html Página 6 de 54
Manual de Webpack
Para ello podemos probar simplemente a invocar el comando de consola "webpack", que
lanzará el proceso de ejecución en nuestro proyecto.
webpack
Obviamente, el comando nos arrojará unos errores, porque lanzado de este modo concreto
observará que no tiene la estructura de proyecto que espera encontrar de manera
predeterminada.
En este punto y para resolver estos asuntos, tenemos dos opciones. Una es comenzar a
configurar Webpack en el archivo webpack.config.js, para hacer que trabaje adaptándose a
nuestro proyecto. La otra es adaptar nuestro proyecto para conseguir que encuentre las cosas
donde se espera. Vamos a comenzar por adaptarnos nosotros a Webpack y luego veremos el
archivo de configuración para conseguir que trabaje como nosotros necesitemos.
http://desarrolloweb.com/manuales/manual-webpack.html Página 7 de 54
Manual de Webpack
Webpack puede ejecutarse de dos modos distintos, dependiendo de cómo deseemos que
produzca el empaquetado de los archivos.
Nota: por agilidad y si lo deseas, puedes crear los script en el archivo package.json para
guardar los comandos de ejecución de Webpack que te parezcan oportunos.
Además Webpack también tiene un punto de salida predeterminado, que es para Javascript el
archivo dist/main.js. Dentro de dicho fichero colocará el bundle con todo nuestro Javascript.
Esta configuración ni tiene por qué adaptarse a nuestro proyecto actual o nuestras preferencias
de desarrollo, así que dentro de poco aprenderemos a cambiarla. Sin embargo, de momento y a
modo de prueba vamos a crear el punto de inicio que Webpack está esperando, para ver lo que
pasa.
Creamos entonces, colgando de la raíz de nuestro proyecto, la carpeta "src" y dentro un archivo
llamado "index.js".
http://desarrolloweb.com/manuales/manual-webpack.html Página 8 de 54
Manual de Webpack
Ahora podrás ejecutar de nuevo Webpack para obtener una salida diferente. Puedes elegir el
modo de que desees, producción o desarrollo. En ambos casos observarás cómo se crea nuestra
carpeta y archivos de destino.
Al ejecutarse podrás observar cómo se crea el archivo "main.js" dentro de una carpeta "dist".
Por consola ya no nos arroja ni errores ni warnings, por lo que se ha comprobado que podemos
comenzar a trabajar con Webpack sin necesidad de haber realizado configuración alguna.
Puedes observar el resultado del archivo main.js para comprobar las transformaciones que ha
realizado en nuestro código Javascript. Probablemente al final de este chorro de código
encuentres la línea o líneas de Javascript que habías escrito en tu index.js. El resto de código
son cosas que necesita Webpack para funcionar.
Esta imagen es el código que se ha producido para modo "production". Abajo ves el código que
yo escribí en el index.js.
http://desarrolloweb.com/manuales/manual-webpack.html Página 9 de 54
Manual de Webpack
Como un primer paso de uso de Webpack ha estado bien, pero recuerda que tienes mucho más
que aprender para ir adquiriendo nuevas y sorprendentes habilidades.
Te vamos a aportar para finalizar un vídeo donde ves este proceso realizado paso a paso, de
instalación de Webpack y puesta en marcha de nuestro proyecto. Tanto si te quedó claro el
contenido de este artículo como si no, te vendrá bien verlo, pues se explican muchas cosas
interesantes y modos de trabajo diferentes con Webpack básico que no hemos llegado a
comentar en este artículo.
Los vídeos de este artículo son dos cortes de la primera clase del Curso de Webpack 4 de
EscuelaIT. En la página del curso tienes otros vídeos de acceso gratuito que seguramente te
interesarán si quieres aprender a usar Webpack.
http://desarrolloweb.com/manuales/manual-webpack.html Página 10 de 54
Manual de Webpack
Vamos a comenzar una segunda entrega de los artículos dedicados a Webpack, en la que
continuaremos aprendiendo cosas interesantes para el uso de esta potente herramienta de
desarrollo frontend.
Recuerda que para usar Webpack necesitas iniciar tu proyecto con npm y luego instalar el
propio Webpack, como dependencia de desarrollo, en local. Esto lo consigues ejecutando los
siguientes comandos de terminal, desde el directorio raíz de tu proyecto.
npm init
Ahora vamos a crear una carpeta donde colocaremos nuestro código fuente, de origen, de
nuestra aplicación, así como el archivo con el código Javascript raíz.
mkdir src
cd src
touch index.js
Aquí tenemos todo lo necesario para que Webpack funcione, aunque hasta el momento no
hemos visto nada que no se conociera del artículo anterior de Webpack. Cualquier duda, por
favor consulta la referencia.
Scripts npm
Ahora, como novedad, vamos a crear unos scripts de npm con los que podamos invocar
fácilmente Webpack. Estos scripts se tienen que colocar en el archivo package.json, en la
propiedad "scripts".
http://desarrolloweb.com/manuales/manual-webpack.html Página 11 de 54
Manual de Webpack
Básicamente lo que escribimos son los comandos de uso de Webpack, tanto en la etapa de
desarrollo como en la etapa de producción.
"scripts": {
},
Ahora podemos ejecutar perfectamente esos scripts de npm, desde la raíz del proyecto, el lugar
donde está el propio package.json, con un comando de consola como este:
Verás como Webpack se pone a funcionar y crea la carpeta "dist" con los archivos generados
por el empaquetador.
Hasta aquí todavía no hemos visto nada demasiado nuevo, pero al menos tenemos todo lo
necesario para comenzar a trabajar. Abordaremos entonces ya mismo la configuración de
Webpack.
Archivo webpack.config.js
Este archivo se debe colocar en la raíz del proyecto, en la misma carpeta que el package.json. Al
menos es donde Webpack intentará encontrarlo, pues también podríamos colocar la
configuración en otra ruta o en otro nombre de archivo si lo vemos conveniente, en cuyo caso
deberíamos personalizar los comandos invocación de Webpack con el parámetro "--config"
seguido de la ruta completa al archivo de configuración.
El archivo webpack.config.js contiene código Javascript, que será procesado por NodeJS. Por
ello, si no conoces NodeJS seguramente algunas cosas te resultarán un poco diferentes del
código Javascript que usas en el entorno de ejecución del navegador. Recuerda que puedes
aprender en el Manual de NodeJS, o resolver diversas dudas sobre este entorno de ejecución
Javascript.
http://desarrolloweb.com/manuales/manual-webpack.html Página 12 de 54
Manual de Webpack
Este archivo tiene que realizar una exportación de un objeto Javascript, que contiene todas las
propiedades necesarias para alterar las configuraciones predeterminadas de Webpack, así
como instanciar los plugins de los plugins y definir los cargadores que queramos usar para
nuestro proyecto.
Comenzaremos con una estructura básica, que iremos complicando poco a poco, a medida que
agreguemos más y más configuración al archivo. De momento comenzamos con esta base de
código.
module.exports = {
output: {
},
En este archivo estamos configurando tan solo una de las muchas cosas que Webpack permite
alterar, el directorio de salida de los paquetes (bundles) generados. Para quien no conozca
NodeJS vamos a dar una serie de notas interesantes:
Con la primera línea estamos trayendo un módulo llamado "path" que forma parte de
NodeJS, que nos sirve para trabajar con archivos y rutas de directorios. Los módulos en
NodeJS sirven para ordenar el código. Cada archivo Javascript es un módulo, que
puede importar código de otros módulos y exportar código de este módulo hacia afuera.
Require es la sentencia que se usa para importar un módulo y 'path' es el nombre del
módulo que deseamos importar. Dicho módulo se almacena en una constante llamada
"path".
Con "module.exports" estamos exportando hacia afuera código Javascript. Todo el
código que esté dentro de exports se podrá usar fuera del archivo / módulo que estamos
programando.
path.resolve(), el método resolve del módulo path, sirve para resolver una secuencia de
cadenas con caminos, en un camino completo. Es como una especie de concatenador de
caminos, que devuelve un camino absoluto juntando todas las secuencias.
__dirname equivale en NodeJS al directorio del disco duro donde está situado nuestro
módulo, en el que estamos programando.
Ahora que ya tenemos alguna idea básica de NodeJS, podemos comprender qué es lo que le
estamos indicando a Webpack. Es bien simple, pues solamente estamos alterando una de las
muchas cosas que se pueden configurar, en este caso el directorio de salida de los archivos,
bundles o paquetes, generados.
Como podrás suponer, a través de la propiedad "output" del objeto que estamos exportando en
el webpack.config.js, estamos definiendo la ruta donde se colocarán los bundles, que en este
caso será la concatenación entre la ruta donde se encuentra webpack.config.js y una cadena de
camino extra. Por tanto, ahora Webpack colocará los bundles en la carpeta "public_html/js" en
lugar de la carpeta "dist", estando esa carpeta dentro de nuestro proyecto.
http://desarrolloweb.com/manuales/manual-webpack.html Página 13 de 54
Manual de Webpack
El siguiente código de webpack.config.js nos muestra una configuración más personalizada del
proyecto, con las propiedades entry y output.
module.exports = {
output: {
filename: 'app.js'
},
entry: {
main: './fuentes/inicio.js'
Output filename: Sirve para decirle el nombre del archivo del bundle que va a
generar.
Entry main: sirve para indicar el archivo de Javascript de entrada de este proyecto.
A lo largo del manual de Webpack iremos explicando otras propiedades que podemos usar en
el archivo webpack.config.js, con ejemplos prácticos. De todos modos, para ir adelantando,
algunas cosas que se podrán definir son:
Nota: Recuerda que los loaders son transformaciones que se aplican en el código fuente de
http://desarrolloweb.com/manuales/manual-webpack.html Página 14 de 54
Manual de Webpack
Conclusión
De momento y para terminar puedes poner en marcha lo que hemos realizado hasta el
momento en este artículo, lanzando el comando:
Apreciarás que el bundle de código de nuestra aplicación se almacena en la carpeta que hemos
definido en el archivo webpack.config.js, con lo que ya hemos podido comenzar a personalizar
el comportamiento de Webpack para nuestro proyecto.
http://desarrolloweb.com/manuales/manual-webpack.html Página 15 de 54
Manual de Webpack
Una de las operaciones más importantes que se realizan mediante Webpack, u otros sistemas
de empaquetado de código es la traducción / compilación del código Javascript de las
aplicaciones. Mediante esta operativa, que abordaremos en los próximos artículos del Manual
de Webpack, podrás distribuir tu código Javascript creado usando las últimas características
del lenguaje, para que se pueda ejecutar correctamente en todos los navegadores. Podrás usar
ES6 o incluso ES7 o TypeScript y una vez transpilado será compatible todos los navegadores.
Además te enseñaremos el mecanismo para distribuir un código apropiado para cada
navegador (ES5 para los antiguos y ES6 para los navegadores más modernos).
En un proyecto frontend es importante usar las últimas novedades del lenguaje Javascript. A
veces porque es útil y productivo para el desarrollador, ya que generalmente las novedades del
lenguaje permiten un código más resumido, que ofrece mayor facilidad de mantenimiento. A
veces simplemente porque lo exige el stack de tecnologías y los frameworks utilizados.
Claro que no siempre todas las novedades del lenguaje están disponibles en todos los
navegadores, por ello es fundamental la operación del transpilado de código. Seguramente a
estas alturas todo el mundo sepa qué es transpilar, pero por si algún despistado lo desconoce,
es una operación entre el compilado y la traducción, mediante la cual el código creado con
versiones superiores de Javascript (o supersets de Javascript como TypeScript) es
transformado en código compatible con todos los navegadores del mercado.
Nota: Durante el artículo vamos a ofrecer alternativas de trabajo con Babel 6 y Babel 7, ya
que hace pocos días se ha presentado Babel7 y los nombres de paquetes de npm de BabelJS
han cambiado.
http://desarrolloweb.com/manuales/manual-webpack.html Página 16 de 54
Manual de Webpack
Babel loader
Para transpilar Javascript la herramienta que usaremos será BabelJS. No es una utilidad
específica de Webpack, sino una herramienta autónoma que podemos usar en muchos flujos
de desarrollo frontend. Para usarla dentro de Webpack usaremos el babel loader.
El primer paso será entonces instalar esta dependencia de desarrollo, con el siguiente comando
de consola.
npm i -D babel-loader
npm i -D babel-core
Actualización: Acaba de salir Babel 7. Esta release ha provocado un cambio en los nombres
de las dependencias npm que necesitamos para usar Babel, por lo que vamos a dar los
comandos de instalación que hoy deberías usar para proyectos nuevos. Los loader de Webpack,
así como los plugins de Webpack que usan Babel por debajo, siguen siendo compatibles con
Babel 7 y se instalan igual.
http://desarrolloweb.com/manuales/manual-webpack.html Página 17 de 54
Manual de Webpack
Una vez instalado, tenemos que configurar Webpack para hacer funcionar a Babel, mediante el
archivo webpack.config.js.
module.exports = {
module: {
rules: [
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
Hasta aquí hemos realizado la configuración relativa a Webpack, pero aún nos queda algo de
trabajo para configurar Babel.
Básicamente este paso consiste en decirle a Babel el tipo de transpilado que debe realizar.
Ahora en Babel se recomienda usar un "preset" que indica que la versión de nuestro código
Javascript es ES2015, ES2016 y ES2017 (todo junto). De este modo conseguimos contar con
todas las novedades del estándar de Javascript de los últimos años.
http://desarrolloweb.com/manuales/manual-webpack.html Página 18 de 54
Manual de Webpack
Tenemos que comenzar instalando la dependencia del preset "env". Primero veamos la
alternativa de Babel 6:
npm i -D babel-preset-env
npm i -D @babel/preset-env
El archivo de configuración .babelrc contiene código JSON. En él tenemos que indicar que
vamos a usar el preset que se acaba de instalar "env".
"presets": ["env"]
"presets": ["@babel/preset-env",]
Tal como hemos configurado nuestro proyecto, podemos usar ahora el código Javascript con
las nuevas versiones. Veamos un poco de código que podríamos colocar en el archivo de
nuestro "entry point".
class miClase {
constructor(x, y) {
this.x = x;
http://desarrolloweb.com/manuales/manual-webpack.html Página 19 de 54
Manual de Webpack
this.y = y;
muestraX() {
console.log(this.x);
sumar(...valores) {
let suma = 0;
for(let i in valores) {
suma += valores[i];
return suma;
miObj.muestraX();
console.log(miObj.sumar(2, 4, 5, 6));
Nota: Este código Javascript tiene un par de detalles en ES6, como el uso de clases de
programación orientada a objetos, el trabajo con otras declaraciones de variables como
const y let, así como el operador rest. Si no conoces todas estas cosas las puedes aprender el
Manual de ES6.
Imports de ES6
Otra cosa interesante que podemos hacer ahora que estamos habilitados para trabajar con
Javascript ES2015 es la realización de imports, con lo que nos podemos traer el código de otros
módulos.
Esto es algo de vital importancia para el mantenimiento de las aplicaciones, ya que al poder
dividir el código en diversos archivos, éstos quedan más reducidos, manejables y concisos.
Podemos poner cada cosa en su sitio y resultará más sencillo de organizarnos.
import './miModulo.js';
Esto quiere decir que tenemos un archivo llamado miModulo.js que estará en la misma carpeta
que el index.js. Al hacer el bundle, Webpack juntará el código del index.js con el código de
miModulo.js en el Javascript de salida.
Nota: Si no lo dominas todavía, puedes aprender más sobre los módulos de Javascript
http://desarrolloweb.com/manuales/manual-webpack.html Página 20 de 54
Manual de Webpack
ES2015.
Otra cosa que puedes importar de manera sencilla son las librerías de dependencias de
terceros, que has instalado vía npm. La manera de hacerlo dependerá un poco de la
organización de la librería, pero en líneas generales será más o menos así.
Primero instalar la correspondiente librería usando npm. Por ejemplo, así instalamos moment,
una potente y popular librería para trabajo con fechas.
npm i moment
Ahora, desde el archivo Javascript donde quieras usar moment, lo tendrás que importar con el
siguiente código de muestra.
En este caso tenemos que importar dos cosas. La primera es la propia librería moment y la
segunda sirve para importar los "locales" para el español, es decir, todas las traducciones de la
librería que usas para que los mensajes te salgan en español.
Este paso será igual que siempre. Recuerda que podemos ejecutar Webpack directamente
desde la línea de comandos, con la siguiente instrucción.
Pero que generalmente tendrás tus scripts de npm para hacer algo como "npm run build", tal
como ya explicamos en el artículo sobre configuración de Webpack.
Una vez se haya producido el bundle con nuestro código, tendremos todo unido en un único
archivo de Javascript, que será compatible con todos los navegadores, incluso aquellos que
sólo entienden ES5 (principalmente IE 11 y anteriores).
Al hacer los bundles, Webpack nos ofrecerá una salida como la siguiente. En ella podremos
http://desarrolloweb.com/manuales/manual-webpack.html Página 21 de 54
Manual de Webpack
comprobar que se están uniendo varios archivos de código Javascript, los módulos distintos
que hemos ido importando a lo largo de los ejemplos de este artículo.
Otra cosa que debes hacer, para verificar que está funcionando todo correctamente, es
visualizar el código generado por Webpack, donde no deberían aparecer los códigos de ES6,
como las clases, los imports, los "let" y "const", etc. Pero, por supuesto, la prueba de fuego será
ejecutar ese código en un Internet Explorer, 11 o anterior, donde debería todo funcionar
exactamente del mismo modo que en un navegador moderno (Chorme, Safari, Firefox) donde
sí está disponible Ecmascript 2015.
Como hemos indicado, el archivo webpack.config.js nos permite indicar que debemos procesar
"babel-loader" para cada archivo Javascript. Además de esta configuración también podemos
indicarle la opción del preset, lo que nos ahorraría crear el archivo babel.rc que hemos
señalado anteriormente.
El código de configuración nos quedaría entonces más o menos como podemos ver a
continuación, en webpack.config.js:
rules: [
test: /\.js$/,
use: {
loader: 'babel-loader',
Esta ventaja interesante que ofrece esta alternativa es que permite usar presets o
configuraciones de transpilado diferentes dependiendo del archivo de configuración de
Webpack que estemos cargando en cada momento.
http://desarrolloweb.com/manuales/manual-webpack.html Página 22 de 54
Manual de Webpack
En la actualidad la mayoría de los navegadores soportan ES6. Sin embargo, gran cantidad de
desarrolladores continúan distribuyendo el código Javascript transpilado, en ES5, para
asegurar la compatibilidad con todos los navegadores.
Pero debemos preguntarnos ¿es esa la mejor estrategia? La verdad es que no. El transpilado es
un mal necesario en muchos casos, pero podemos evitarlo para los navegadores que están
preparados, acelerando la descarga y el procesamiento del código, lo que permitrá mejorar el
rendimiento de los sitios y aplicaciones web.
En este artículo queremos explicar la configuración de Webpack para que puedas distribuir en
tu aplicación frontend la versión del código que más convenga a cada navegador. Los que sean
compatibles con ES6, recibirán el código original y aquellos browsers antiguos, que solo
soportan ES5, recibirán el código transpilado.
Cuando se transpila de ES2015 (ES6) a ES5, el código se transforma, para que sea compatible
con todos los navegadores. En esa transformación ocurre que el código aumenta de tamaño, ya
que se tienen que emular características disponibles ahora de manera nativa por los
navegadores.
Ese aumento de tamaño es sensible. No son unas pocas KB, sino que en ocasiones puede
representar casi el doble de tamaño. Por ejemplo, en un sitio web de tamaño minúsculo, un
bundle Javascript escrito en ES6 puede pesar en torno de 180 Kb. Una vez transpilado puede
acabar pesando 334 Kb. Con el pequeño proyecto que he construido para ilustrar el artículo
vamos a demostrarlo. En esta imagen puedes ver los tamaños de los bundles, con el mismo
código transpilado y sin transpilar.
http://desarrolloweb.com/manuales/manual-webpack.html Página 23 de 54
Manual de Webpack
Ahora imagina en términos de aplicaciones grandes, donde podemos tener varios cientos de
Kb de diferencia. Te darás cuenta de lo importante que es ofrecer para cada navegador un
código optimizado según sus capacidades. Pero además, piensa que el tiempo de descarga no
es único precio a pagar por el transpilado. Si el navegador debe procesar el doble de código
Javascript para hacer lo mismo, el rendimiento también se verá afectado.
Cómo configurar Webpack para que genere dos bundles con configuraciones
distintas de Babel
Bien, vamos entonces a abordar la práctica, para conseguir primero los dos bundles que
queremos como respuesta al proceso de producción del código.
Para conseguirlo además vamos a usar Babel, que es quien realiza el transpilado realmente.
Debemos producir por tanto dos configuraciones para Babel, una con transpilado y otra sin
transpilado.
Nota: En nuestro ejemplo tendremos una configuración con transpilado y otra sin
transpilado, pero en muchos casos podríamos tener realmente dos configuraciones de babel
con transpilado, pues podríamos usar construcciones como async/await, que están
disponibles solamente en ES7, y por tanto fuera del alcance actual de los navegadores. Así
pues, podríamos tener un código transpilado a ES5 para navegadores antiguos y otro código
transpilado a ES6 para los navegadores modernos. En cualquier caso, lo hagas como lo
hagas, siguen siendo dos configuraciones diferentes de Babel.
http://desarrolloweb.com/manuales/manual-webpack.html Página 24 de 54
Manual de Webpack
module.exports = {
module: {
rules: [
test: /\.js$/,
//exclude: /node_modules/,
loader: "babel-loader"
},
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',
})
Por otra parte tendremos un archivo de configuración especial, que no realiza transpilado. Este
archivo es bastante similar, con la diferencia que no configuramos Babel en él.
module.exports = {
output: {
filename: 'main-es6.js'
},
plugins: [
new HtmlWebpackPlugin({
template: 'dist/index.html',
}),
Nota: En tu proyecto podría ser una configuración que transpila de ES7 a ES6, si fuera
necesario según tu código Javascript.
http://desarrolloweb.com/manuales/manual-webpack.html Página 25 de 54
Manual de Webpack
Estas dos configuraciones se tienen que ejecutar en llamadas diferentes a Webpack, la primera
y la segunda, por ese orden. Para resumir esta tarea podemos crear unos scripts npm, en el
package.json, como estos:
"scripts": {
},
Module y nomodule
Este punto es importante, puesto que una vez tenemos dos archivos con código orientado a
navegadores que soportan ES6 y a los que solamente llegan a ES5, debemos aleccionar a cada
cliente web a obtener el script más adecuado para él.
Conseguirlo es muy sencillo gracias a la etiqueta script, en la que podemos agregar atributos
específicos para decirle al navegador cuál es su archivo de script para cargar. El atributo
type="module" indicará a los navegadores que ese código está escrito con ES6 (ES2015).
Mientras que el atributo "nomodule" indicará que ese código sólo está indicado para los
navegadores que no entienden ES6.
Nota: Si deseas obtener una información más detallada de esta práctica para entregar el
código adecuado de Javascript dependiendo de la compatibilidad de los navegadores, te
http://desarrolloweb.com/manuales/manual-webpack.html Página 26 de 54
Manual de Webpack
El problema que se nos puede presentar en este punto, derivado del uso de Webpack, es que
los códigos de los scripts se inyectan en la página mediante el uso de HTML Webpack Plugin.
Este plugin, de casa, no está preparado para poder colocarle atributos específicos a las
etiquetas SCRIPT, por lo que tenemos que usar un complemento del que no hemos hablado
todavía.
Una vez instalado su uso es bastante similar al conocido HTML Webpack Plugin. Tenemos
primero que hacer el require y a continuación instanciar el plugin en el array "plugins" de la
configuración Webpack.
Veamos entonces cómo nos quedarían los dos archivos de configuración usados para este
ejemplo de Webpack 4, una vez integramos el uso de Script Extension for HTML Webpack
Plugin.
Archivo config.webpack.js
module.exports = {
module: {
rules: [
test: /\.js$/,
//exclude: /node_modules/,
loader: "babel-loader"
},
http://desarrolloweb.com/manuales/manual-webpack.html Página 27 de 54
Manual de Webpack
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
hash: true,
templateParameters: {
}),
new ScriptExtHtmlWebpackPlugin({
custom: [
test: /\.js$/,
attribute: 'nomodule',
},
})
Recuerda que con el anterior script de configuración estamos definiendo el código para los
navegadores que solo tienen soporte a ES5. Por ello, se insertará en el atributo "nomodule" en
la etiqueta del script.
Archivo webpack.config-es6.js
Este el script de configuración para producir el código ES6, para navegadores modernos.
module.exports = {
output: {
filename: 'main-es6.js'
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'dist/index.html',
hash: true
}),
new ScriptExtHtmlWebpackPlugin({
module: 'js'
})
http://desarrolloweb.com/manuales/manual-webpack.html Página 28 de 54
Manual de Webpack
Nota: Recuerda leer la documentación completa de Script Extension for HTML Webpack
Plugin en su propia página de Github.
Con estos cambios, conseguiremos unas etiquetas de script como las siguientes. Podrás
observar la colocación de los atributos para module y nomodule.
Conclusión
Hemos visto cómo generar código de script con diversos sabores, adaptado o no a las últimas
características de Javascript, ES2016 y ES5. Además hemos visto cómo inyectar esos scripts de
modo que cada navegador descargue y use el más apropiado según su compatibilidad.
Ha sido una práctica un poco más compleja de las que habíamos visto anteriormente en el
Manual de Webpack, pero que resultará muy útil para la optimización de sitios y aplicaciones
modernas. Sin duda será fundamental en aplicaciones web complejas, con gran cantidad de
Javascript adaptado para aprovechar las últimas ventajas del lenguaje.
http://desarrolloweb.com/manuales/manual-webpack.html Página 29 de 54
Manual de Webpack
Otra operativa muy común con Webpack es la que nos permite transformar en CSS estándar el
código escrito mediante lenguajes de preprocesadores CSS como Sass. La podrás conocer a
continuación.
Una de las tareas típicas del desarrollo frontend actual es el procesamiento de CSS, para
ejecutar los correspondientes preprocesadores y producir un código de hojas de estilo
compatible con los navegadores y optimizado para una rápida descarga.
Esta tarea de procesamiento del código CSS permite pasar nuestro código escrito en Sass, Less,
etc. en código CSS estándar, compatible con los navegadores. Para realizar esta acción los
distintos preprocesadores tienen herramientas específicas, pero nosotros queremos usar
Webpack, básicamente porque así podremos tener un mismo flujo de trabajo para todos los
lenguajes o componentes del proyecto frontend.
Este paso requiere la transformación del código CSS, para lo que tenemos que usar un loader
distinto de los que hemos visto hasta este momento en el Manual de Webpack. En este artículo
explicaremos los pasos necesarios para configurar la herramienta y poder hacer el paso del
procesamiento del código Sass en código CSS estándar.
Recordemos que en Webpack se trabaja con un punto de entrada, que es un archivo Javascript.
Webpack analiza el código de este archivo JS para producir los correspondientes bundles de
código. En el caso que nos ocupa, el procesamiento del CSS, Webpack necesita encontrar el
código CSS a partir del punto de entrada. Por tanto, aunque parezca un poco raro, dentro de
nuestro Javascript tendremos que hacer el import del código CSS.
http://desarrolloweb.com/manuales/manual-webpack.html Página 30 de 54
Manual de Webpack
/* css */
import './css/estilos.css';
Nota: La primera vez que ves ese import de un archivo CSS dentro del código Javascript te
puedes sorprender un tanto, pues resulta bastante antinatural. Sin embargo, es la manera
habitual de trabajar en las aplicaciones React, por lo que realmente es algo común cuando
se trabaja con Webpack.
Como dentro de un archivo Javascript no podemos incluir código CSS, si ejecutas el proceso de
Webpack en estos momentos apreciarás un error, producido por la sintaxis del archivo
estilos.css. Es normal que esto ocurra, pues en este archivo colocaremos código CSS, que el
intérprete de Javascript no acepta como válido. Pero no te preocupes, porque realmente nos
faltaba un paso muy importante para dejarlo todo listo.
Ahora vamos a sacar todo el CSS que se ha importado dentro del Javascript, para enviarlo a un
archivo de CSS común. Para esta tarea necesitamos un par de paquetes.
Plugin mini-css-extract-plugin
Para realizar esta tarea tenemos que usar un plugin llamado mini-css-extract-plugin, que
realizará la extracción de todo el código CSS que tengamos dentro de Javascript. Este plugin
creará el archivo .css para llevar a producción.
Loader css-loader
Recuerda además que las transformaciones del código en Webpack se realizan mediante
loaders. Los Loaders permiten procesar y transformar el código fuente de tu aplicación, según
se importa en el archivo Javascript mediante la sentencia import. Puedes pensar en los loaders
como una especie de tareas a realizar por Webpack. En el caso del css-loader sirve para poder
importar CSS como si fueran módulos Javascript.
http://desarrolloweb.com/manuales/manual-webpack.html Página 31 de 54
Manual de Webpack
Ahora veamos la configuración que tenemos que realizar de Webpack, con css-loader y mini-
css-extract-plugin, para realizar las siguientes acciones:
Retirada de todo código CSS, para que no figure dentro del código Javascript
Creación de un archivo .css con el código CSS que se ha importado
Inyección del código CSS dentro del código HTML, con la etiqueta LINK, dirigida hacia
el archivo .css creado.
Además, para el paso de la inyección del código CSS dentro del HTML generado tienes que
usar html-webpack-plugin, como se explicó en el artículo dedicado a HtmlWebpackPlugin.
module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
hash: true
}),
new MiniCSSExtractPlugin()
],
module: {
rules: [
test: /\.css$/,
loader: [
MiniCSSExtractPlugin.loader,
"css-loader"
http://desarrolloweb.com/manuales/manual-webpack.html Página 32 de 54
Manual de Webpack
new MiniCSSExtractPlugin({
filename: "estilos.css",
})
Una vez que tenemos montado todo el sistema para el procesamiento del CSS, adaptarlo para
trabajar también con Sass, u otro preprocesador de nuestra preferencia, será muy sencillo.
Nota: Si quieres aprender Sass te recomendamos la lectura del Manual de Sass. Es una
herramienta altamente recomendable para el desarrollo frontend, que te permitirá generar
código CSS más mantenible y con más productividad.
Básicamente necesitas instalar dos paquetes nuevos en tu proyecto. Por un lado node-sass que
es quien tiene el código para poder preprocesar Sass desde el lenguaje NodeJS. Por otro lado
sass-loader que sirve para que desde Webpack puedas hacer las transformaciones pertinentes
sobre tu código CSS.
Luego nos toca configurar el correspondiente loader. Algo que es muy sencillo, pues solamente
lo tenemos que agregar al array de loaders que tenemos en la regla de transformación de
nuestro CSS.
rules: [
test: /\.scss$/,
loader: [
MiniCSSExtractPlugin.loader,
"css-loader",
'sass-loader'
http://desarrolloweb.com/manuales/manual-webpack.html Página 33 de 54
Manual de Webpack
Solo un detalle que no debe pasar desapercibido: fíjate que la expresión regular de "test" ha
cambiado, ya que en Sass se suelen usar extensiones de archivos "scss" en lugar de "css". Es
por ello que ahora debemos extraer el CSS que viene de archivos .scss. Obviamente, si sigues
usando extensión .css, aunque escribas en Sasss (algunos desarrolladores lo hacen así), ese
"test" tendría que tener la expresión regular del ejemplo anterior.
Eso es todo! ahora al ejecutarse Webpack se generará el Código CSS de nuestra aplicación y se
meterá en un archivo .css, separado del código Javascript. Además el código Sass se
preprocesará, de modo que tendremos únicamente código CSS compatible con todos los
navegadores.
Solo ten en cuenta de nuevo que los loaders usados para esta regla tienen que ejecutarse en el
orden correcto, definido por la posición dentro de la declaración del array. Por ejemplo, si
intentas colocar el "sass-loader" antes del "css-loader" apreciarás que Webpack te responde
con un error.
Conclusión
Hemos conocido los paquetes necesarios para producir las transformaciones necesarias en el
código CSS, incluyendo la posibilidad de escribir código Sass y preprocesarlo para obtener el
código CSS estándar, compatible con los navegadores.
http://desarrolloweb.com/manuales/manual-webpack.html Página 34 de 54
Manual de Webpack
Webpack es la herramienta más extendida para producir y optimizar el código front-end de las
aplicaciones web. En estos artículos analizamos y explicamos los flujos de trabajo del
desarrollo con Webpack en aplicaciones frontend modernas.
En este artículo vamos a continuar ofreciendo las guías esenciales para aprender a usar
Webpack. Es un artículo que ofrece un paso más en la configuración de un entorno de trabajo
para un proyecto frontend. Recuerda que en el punto anterior del Manual de Webpack
pudimos aprender a transpilar código a ES5 y hemos generado nuestro primer bundle a partir
de varios módulos Javascript.
Lo que nos proponemos ahora es colocar el archivo del bundle en el código HTML. Alguien
podría pensar que ésta sería una tarea completamente trivial, pues realmente se trata de
colocar una etiqueta SCRIPT en un archivo HTML. Lo podríamos hacer de manera manual una
vez y listo! Pero no siempre será así. El plugin que estamos aprendiendo puede servirnos para
inyectar Javascript, CSS, el manifest o archivos favicon. Incluso facilitarnos la tarea de enlazar
con un archivo Javascript que tenga un hash al final, de modo que en cada actualización
cambie su nombre y se eviten efectos poco deseables en la etapa de desarrollo, como que se
cacheen por el navegador en las actualizaciones de página.
Todo lo que vamos a necesitar es un plugin de Webpack llamado HTML Webpack Plugin.
http://desarrolloweb.com/manuales/manual-webpack.html Página 35 de 54
Manual de Webpack
npm i -D html-webpack-plugin
Ahora podemos usar ese plugin desde la configuración de Webpack. Se trataría de hacerlo en
dos pasos, pero vamos a ver el código completo de nuestro webpack.config.js.
module.exports = {
plugins: [
new HtmlWebpackPlugin()
Obtenemos el código del plugin, con un require, que es la manera adecuada de cargar
módulos en NodeJS. Estamos trayendo el módulo que se acababa de intalar desde npm,
y almacenándolo en una constante.
Luego en el array de plugins se instancia el nuevo HtmlWebpackPlugin.
Ahora podemos ejecutar webpack para comprobar esta configuración, con el comando
"webpack --mode production" o algo como "npm run build" si es que has creado el
correspondiente script en package.json.
Además, en el código del archivo HTML generado observarás que, sin necesidad de pedirle
nada, ya coloca una etiqueta SCRIPT que cargará el código de main.js, el bundle principal.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
</html>
Este plugin tiene la posibilidad de usar una serie de opciones de diverso interés. Para cargarlas
usamos un objeto que tenemos que enviar como parámetro en la instanciación del plugin.
Algunas de las más destacadas son.
http://desarrolloweb.com/manuales/manual-webpack.html Página 36 de 54
Manual de Webpack
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
templateParameters: {
})
Ahora veamos el código de nuestro template, donde veremos cómo se insertan los parámetros.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1><%= encabezamiento%></h1>
</body>
</html>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
http://desarrolloweb.com/manuales/manual-webpack.html Página 37 de 54
Manual de Webpack
</head>
<body>
</html>
Como resultado de esta acción tendríamos en la carpeta "dist", o cualquier otra que tengas
configurada como output en webpack.config.js, los archivos de:
Localizando ese index.html con el explorador de archivos o finder, podríamos hacer doble clic
sobre él para abrirlo y comprobar que el código transpilado, e inyectado como script en el
HTML, se está ejecutando correctamente.
Ya que lo mencionábamos al principio del artículo, acabamos explicando cómo hacer uso de un
hash para el nombre del archivo del bundle. Es tan sencillo como activar una de las
configuraciones de instanciación del plugin.
plugins: [
new HtmlWebpackPlugin({
hash: true
})
Una vez ejecutado el proceso de build con Webpack, podrás apreciar que en el HTML generado
ahora aparece el hash en la ruta del script del bundle. Verás algo como esto:
http://desarrolloweb.com/manuales/manual-webpack.html Página 38 de 54
Manual de Webpack
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'src/index.html',
hash: true,
templateParameters: {
}),
new HtmlWebpackPlugin({
filename: 'standar.html'
}),
new HtmlWebpackPlugin({
filename: 'index2.html',
template: 'src/index.html',
templateParameters: {
}),
new ScriptExtHtmlWebpackPlugin({
custom: [
test: /\.js$/,
attribute: 'nomodule',
value: 'nomodule'
},
})
Fíjate que los filemane cambian para cada instanciación. Además, si estamos enviando
parámetros al template, podremos generar código HTML con distinto contenido, lo que nos da
una idea de cómo generar código estático a través de Webpack. No obstante, existen diversos
sistemas de templates que nos pueden ayudar mejor en esta tarea, así como librerías más
complejas para conseguir generar esos archivos estáticos a partir de datos que tengamos en
algún depósito de almacenamiento.
Conclusión
HTML Webpack Plugin es uno de los plugins indispensables para Webpack. Esperamos que te
hayamos aclarado algunas de sus utilidades principales. Nos hemos centrado en la inyección
de los scripts Javascript del bundle, pero lo cierto es que hace muchas otras cosas.
http://desarrolloweb.com/manuales/manual-webpack.html Página 39 de 54
Manual de Webpack
Otra de las tareas básicas que necesitaremos hacer en el desarrollo web en general, es disponer
de un servidor donde veamos la web que estamos programando. Además, sería estupendo si
esa web se actualizase automáticamente cada vez que cambiamos alguna cosa en los archivos
de fuente.
Afortunadamente, contar con este servidor de desarrollo en Webpack es más fácil de lo que
resultará a un mono pelar una banana. En este artículo del Manual de Webpack te lo vamos a
explicar con todo detalle. Seguro que te impresionará la rapidez con la que lo consigues. Para
ello usaremos un paquete de npm llamado webpack-dev-server, que realizará toda la tarea
prácticamente sin necesitar configuración. Sólo por este detalle merece la pena usar Webpack.
El primer paso, como siempre, será instalar las dependencias mediante npm. Como casi
siempre en todo el flujo de trabajo con Webpack instalaremos la dependencia en modo
desarrollo, con el flag "-D".
npm i -D webpack-dev-server
http://desarrolloweb.com/manuales/manual-webpack.html Página 40 de 54
Manual de Webpack
Una vez instalado, ya podemos usar nuestro servidor de desarrollo en Webpack. Una de las
novedades de Webpack 4 es que no hace falta configurar el servidor de desarrollo, ya que nos
ofrece una configuración predeterminada que puede servir en muchos de los casos.
Para ponerlo en marcha vamos a crear primero un script npm. Esto lo hacemos en el
package.json, en la propiedad de "scripts".
El conjunto de scripts que podemos tener en nuestro caso podría ser algo como esto, aunque
claro que dependerá de cómo hayas ido configurando Webpack.
"scripts": {
},
El script en concreto que inicia Webpack Dev Server es el "start". En él estamos indicando:
Para abrir el servidor tenemos que ejecutar el script que acabamos de realizar. Esto lo hacemos
desde el terminal, con el comando:
Como hemos configurado con --open el arranque del servidor, se abrirá automáticamente el
navegador, mostrando la web que estamos realizando. Además, este servidor de desarrollo está
configurado automáticamente con live-reload (información extra más adelante).
Nota: como alternativa a los scripts npm, si quieres asegurarte que se ejecuta la versión
local de webpack-dev-server, puedes lanzar el comando: "node_modules/.bin/webpack-
dev-server" (desde la raíz de tu proyecto)
Una vez arrancado webpack dev server la ventana del terminal quedará abierta, mostrando
cualquier actividad de Webpack en relación al proyecto. Por ejemplo, si se actualizan los
archivos de fuente, se mostrará el resultado de la compilación de estos nuevos archivos. La
ventana del terminal permanecerá ocupada con este watcher y no podremos operar para lanzar
nuevos comandos. Obviamente, no es un problema porque siempre podemos lanzar nuevas
ventanas de terminal, pero si queremos detener el servidor es tan sencillo como pulsar CTRL +
C.
http://desarrolloweb.com/manuales/manual-webpack.html Página 41 de 54
Manual de Webpack
A continuación vamos a dar algunos detalles de interés sobre este complemento de Webpack,
que te pueden venir bien durante la etapa de desarrollo de tu proyecto.
Este servidor viene configurado inicialmente con el sistema de live reloading, lo que permite
que cada vez que se cambian y se guardan los ficheros "fuente" de Webpack, se recargue el
navegador automáticamente, mostrando la web con las recientes modificaciones. Esta utilidad
acelera el proceso de desarrollo, pero sobre todo permite una experiencia de desarrollo
bastante más agradable para el desarrollador
Para probarlo simplemente altera cualquier cosa en tu archivo de Javascript, en tus CSS, en el
HTML de tu template… simplemente con guardar el archivo en tu editor se actualizará el
proyecto en el navegador, mostrando los cambios realizados inmediatamente, sin tener que
recargar y sin que la caché del navegador nos incordie, mostrando código antiguo.
Ten en cuenta que webpack-dev-server realiza un transpilado automático de los archivos. Esto
es una ayuda en la mayoría de los casos, pues así la web que estás desarrollando podrá
visualizarse correctamente en navegadores que soportan ES6 y ES5. De manera
predeterminada el transpilado se realizará para soportar las últimas dos versiones de los
navegadores principales.
Por ejemplo, si usas scripts de npm tal como te hemos explicado, el script "start" te podría
quedar de la siguiente manera:
En ese archivo, donde se encuentra el JSON de configuración, igual que tenemos una
propiedad para "plugins", "output", "module", etc., podemos colocar otra justamente para
definir el objeto de configuración para el arranque de nuestro servidor de desarrollo.
http://desarrolloweb.com/manuales/manual-webpack.html Página 42 de 54
Manual de Webpack
devServer: {
port: 9001
Otra configuración muy útil, y necesaria en muchos casos para el servidor de desarrollo es la de
indicar la carpeta donde tenemos el contenido estático. Como contenido estático podemos
encontrar cualquier archivo que no sea procesado por Webpack pero que queramos que sea
entregado también por el servidor de desarrollo.
Por ejemplo, podemos tener imágenes que queramos que se sirvan tal cual (no nos referimos a
imágenes que Webpack haya procesado para optimizar, sino imágenes que tengamos en
nuestro proyecto y que el servidor de desarrollo tenga que mostrar también), o por ejemplo un
archivo JSON estático que queramos leer desde nuestra aplicación en la fase de desarrollo.
devServer: {
port: 9001,
Conclusión
http://desarrolloweb.com/manuales/manual-webpack.html Página 43 de 54
Manual de Webpack
Podemos distinguir aplicaciones frontend, en las que generalmente nos referimos a las SPA
(Single Page Application) y sitios web tradicionales, que son aquellos que están construidos
con múltiples URLs con contenido, como los que creas con CMS como WordPress. En este caso
vamos a ver técnicas que tienen que ver con el uso de Webpack en los sitios web tradicionales.
Webpack se usa muy comúnmente en aplicaciones web de las denominadas SPA (Single Page
Application), pero puedes beneficiarte de esta herramienta desde cualquier otro tipo de sitio
web. En este artículo te vamos a explicar las claves y procedimiento para utilizar Webpack en
sitios que deban servirse a través de otros servidores como Apache, Nginx, etc.
Como sabes, Webpack te permite generar los archivos para llevar a producción la parte
frontend de las aplicaciones. Pero entonces, si el uso de un servidor web del estilo de Apache
viene marcado por tus tecnologías backend, ¿Por qué necesitamos un procedimiento específico
para trabajar con Webpack, que se dedicada al frontend?
Dependiendo del stack de tecnologías frontend que estés usando, puede que sea necesaria la
transformación de ciertos códigos de frameworks y librerías como React, Polymer o
preprocesadores como Sass. Por tanto, puede que haya partes del tu código frontend que no
puedas ejecutar desde el navegador directamente, si es que no se procesan antes por alguna
herramienta del estilo de Webpack. Cuando es necesaria la transformación del código frontend
Webpack permite un flujo de desarrollo más depurado. Gracias a su servidor de desarrollo
somos capaces de obtener de una manera sencilla la habilidad del live-reload, o hot-reload,
produciendo sobre la marcha los archivos necesarios y refrescando automáticamente el
navegador para mostrar los cambios.
El asunto es que, si está haciendo un sitio web tradicional y trabajas con algún lenguaje de
servidor, como PHP, .NET, Python, etc. Seguramente tengas que usar algún servidor web como
Apache o IIS que procese esos lenguajes antes de enviar el código HTML al cliente. Por ese
motivo, no podemos valernos simplemente del servidor de desarrollo que ofrece Webpack y
por tanto no seremos capaces de aprovechar todas las ventajas de su flujo de trabajo. En
resumen, cada vez que se actualice alguna parte de nuestro frontend (tu código Javascript,
TypeScript o el código Sass u otros preprocesadores...) tendremos que lanzar a mano el
proceso de producción de los archivos y refrescar también la página, evitando de cualquier
manera disponible la entrada en funcionamiento de la caché del navegador.
La solución para poder combinar ambos mundos (un desarrollo apurado de tu frontend + el
http://desarrolloweb.com/manuales/manual-webpack.html Página 44 de 54
Manual de Webpack
Instalar webpack-dev-server
Igual que si estuvieras usando Webpack para una aplicación SPA o una PWA, tendrás que
instalar el paquete de Node webpack-dev-server. En este caso, el servidor de Webpack se
encargará simplemente de servir los bundles de tu aplicación, es decir, el Javascript y el CSS.
Mientras que el servidor Apache, Ngnix, IIS (o el que sea) se encargará de servir el código
HTML.
Igual que siempre, podremos poner en marcha el servidor de desarrollo mediante un script
npm, como hemos aprendido anteriormente en el Manual de Webpack.
"scripts": {
Configurar Webpack para definir la ruta donde estarán accesibles los bundles
Ahora vamos a ver una configuración del archivo webpack.config.js en la que podemos definir
una ruta y un puerto para el servidor donde va a estar disponible el código generado por
Webpack.
module.exports = {
devServer: {
http://desarrolloweb.com/manuales/manual-webpack.html Página 45 de 54
Manual de Webpack
port: 9999
},
output: {
publicPath: 'http://localhost:9999/bundles/'
},
devtool: 'inline-source-map'
Esta configuración podrá cambiar según tus preferencias y necesidades de producción de los
bundles. Es solo una muestra para poder guiarte.
El puerto del servidor de desarrollo, que lo he colocado a 9999. Usa el que mejor te
venga. Yo uso ese puerto porque seguramente estará libre, ya que no corresponde con
otros puertos habituales de servidores web o servidores de desarrollo.
El output es el lugar donde estarán públicos tus bundles. Lo puedes usar para saber de
manera sencilla donde estará tu código producido para desarrollo. Luego vamos a usar
esa ruta para poder acceder al bundle que se ha generado.
La configuración devtool: 'inline-source-map' me permite disponer de las ventajas de
los sourcemaps, así cualquier error en la consola Javascript informará del lugar de mi
propio código donde se ha encontrado el problema, y no de la posición del fallo en el
código del bundle.
En tu código backend, colocarás la ruta donde está el bundle del servidor de desarrollo de
webpack. Tal como lo hemos configurado en el paso anterior, la etiqueta SCRIPT que
deberíamos colocar en el HTML sería como esta:
<script src="http://localhost:9999/bundles/main.js"></script>
Fíjate que hemos usado la misma ruta del "publicPath" en la configuración output de
Webpack. Seguida del bundle Javascript que tiene su nombre predeterminado (main.js).
Pero claro, esta etiqueta SCRIPT anterior nos lleva a un servidor de desarrollo, que tenemos
arrancado en nuestro ordenador. Ningún usuario tendrá esa ruta activa. Para producción
tendremos que colocar las rutas de los bundles producidos.
Esta parte la tendrás que hacer de la manera como hemos explicado ya en el Manual de
Webpack. En mi caso uso un archivo de configuración de Webpack específico para cuando voy
a llevar a producción, donde el output está dirigido a una carpeta de Apache. En resumen, para
producción, la etiqueta SCRIPT irá dirigida a una URL dentro del directorio de publicación del
servidor web.
http://desarrolloweb.com/manuales/manual-webpack.html Página 46 de 54
Manual de Webpack
<script src="js/main.js"></script>
Para no tener que ir cambiando la etiqueta SCRIPT todo el tiempo (colocando la válida cuando
estoy desarrollando y la válida cuando estoy publicando el sitio web), facilitando el flujo de
desarrollo y evitando el problema de olvidarme de cambiar la etiqueta SCRIPT al llevar a
producción, lo ideal es crearse un sistema de variables de entorno.
Por ejemplo, podríamos tener una variable de entorno que nos diga si estamos ejecutando el
sitio web en local (desarrollo) o en remoto (producción). El código simplificado al máximo en
PHP podría ser algo como esto:
<?php
if($estoyEnProduccion) {
} else {
?>
Nota: Si no gestionas variables de entorno en tu aplicación y quieres saber algo más sobre
ellas y cómo te pueden ayudar, así como su implementación, puedes ver un artículo
interesante Variables de entorno en PHP con PHP Dotenv.
Conclusión
Con lo que hemos conocido en este artículo del Manual de Webpack podrás sacarle todo el
provecho a esta herramienta en el desarrollo de sitios web tradicionales, ayudando mucho a
mejorar tu flujo y creando una experiencia de desarrollo muy agradable y productiva, ya que
nos permite disponer del live-reload, con una configuración hecha en pocos minutos.
http://desarrolloweb.com/manuales/manual-webpack.html Página 47 de 54
Manual de Webpack
Podrás usar estos consejos para sitios web basados en contenido, con cualquier framework
como Symfony, Laravel, o basados en CMS como WordPress. Así como en cualquier otro
lenguaje de backend donde estés renderizando HTML. Esperamos haberte ayudado.
http://desarrolloweb.com/manuales/manual-webpack.html Página 48 de 54
Manual de Webpack
En los próximos artículos vamos a abordar otros casos de uso de Webpack más avanzados,
pero que resultarán especialmente útiles para sacar todo el provecho de esta herramienta
frontend y crear sitios más avanzados y optimizados.
En aplicaciones web frontend modernas es habitual que el código Javascript ocupe una gran
cantidad de KB. Fácilmente una aplicación frontend puede tener varios cientos de Kilobytes,
algo que es normal, si pensamos en todas las funciones que Javascript realizará dentro de la
aplicación. Quizás no sea algo tan grave, si tenemos en cuenta en la velocidad de las redes
actuales, pero ya se sabe que todo lo que se pueda hacer para mejorar la experiencia de usuario
es más que relevante.
Además, en una aplicación con decenas de vistas o secciones, es importante pensar que un
usuario quizás no va a necesitar nunca muchas partes del código Javascript, pertenecientes a
secciones que quizás no llegue a entrar nunca. Es por ello que resulta muy importante la
posibilidad de trocear los bundles, realizando la tarea conocida por "code splitting".
Con el code splitting conseguimos crear diversos paquetes con el código de Javascript de cada
parte de la aplicación por separado. Generalmente tendremos uno o varios bundles globales,
que necesitas de manera común en todo el sitio y un paquete particular para cada punto de
entrada. Así, cuando por ejemplo un usuario entra en la portada del sitio, se descargará el
código global y únicamente el código particular de la portada, dejando para más adelante la
carga del código específico de cada una de las secciones interiores. Por supuesto, cuando se
acceda como punto de entrada a una sección interna de la aplicación, se requerirá el bundle
global y además el bundle específico de esa sección, dejando aparte el código de la portada y de
las otras secciones de la aplicación.
Este code splitting se realiza de manera automática con el CLI de muchos de los frameworks y
librerías frontend. Pero si nosotros configuramos Webpack a mano tendremos que hacer esta
personalización también de manera manual. Es lo que vamos a abordar en este artículo del
Manual de Webpack.
http://desarrolloweb.com/manuales/manual-webpack.html Página 49 de 54
Manual de Webpack
Primero hay que advertir, para conseguir partir en trocitos tu código Javascript, es que tienes
que haber construido tu aplicación correctamente. Si has colocado todo el código a partir de tu
index.js sería imposible, porque Webpack analizará ese archivo y colocará todo en un mismo
bundle.
Lo que tienes que hacer para conseguir que Webpack pueda producir los bundles es
básicamente tener varios archivos índice, uno para cada sección. Basicamente tendremos un
archivo llamado algo como "index-portada.js" con el código necesario en la portada. Un
"index-dashboard.js", con el código del dashboard, un "index-view_x.js" con el código de la
vista "x". En cada uno de esos index generalmente lo que tendrás será una serie de imports a
cada uno de los submódulos necesarios para cada una de las funcionalidades o componentes
que estás programando para esa parte de tu aplicación.
Así, con el código separado por puntos de entrada, será sencillo que Webpack pueda analizar el
código y crear los bundles correctamente configurados.
Para concretar un poco, aquí dejo dos códigos de dos supuestos puntos de entrada.
import './index';
import './components/vote/dw-vote';
import './components/article/dw-article-vote';
import './index';
import './components/vote/dw-vote';
import './components/faq/dw-faq-vote';
import './components/faq/dw-faq-form';
import './components/faq/dw-answer-vote';
Solo tienes que fijarte en el detalle de que cada uno de estos puntos de entrada, el de los
artículos y el de las FAQ, tiene una serie de imports. Siendo comunes algunos de ellos.
Obviamente algunos de estos imports pueden ser dependencias desarrolladas por nosotros y
http://desarrolloweb.com/manuales/manual-webpack.html Página 50 de 54
Manual de Webpack
otras dependencias de terceros. Además, en cada uno de estos imports puedes tener otros
imports dentro. Webpack será capaz de analizar el código, revisando las dependencias, y las
dependencias de las dependencias para crear los bundles correctamente. Nosotros
simplemente le tenemos que dejar claro el código de cada uno de nuestros posibles puntos de
entrada en la aplicación.
Simplemente tenemos que configurar cada punto de entrada con su index particular. Para
nuestro ejemplo simplificado teníamos dos puntos de entrada, el de artículos y el de FAQ. Cada
uno de ellos los colocamos como entry points.
entry: {
faq: './src/faq.js',
article: './src/article.js',
Luego también tenemos que configurar el output de modo que cada bundle le asigne un
nombre distinto. Para construir personalizar el nombrado del archivo usaremos el nombre de
la propiedad de cada punto de entrada, de esta manera.
output: {
filename: '[name].bundle.js',
El problema que nos podemos encontrar en esta configuración, si lo dejamos tal cual, es que
Webpack repita el código común en cada uno de los bundles. Es decir, tenemos que hacer un
par de pasos adicionales para que el sistema de análisis del código de Webpack sea capaz de
quitar las partes comunes de cada punto de entrada y llevarlas a otros bundles comunes.
Usando SplitChunksPlugin
Este es el plugin que previene la duplicación del código entre los bundles de la aplicación. Para
usarlo simplemente tenemos que configurar el archivo webpack.config.js.
http://desarrolloweb.com/manuales/manual-webpack.html Página 51 de 54
Manual de Webpack
module.exports = {
entry: {
faq: './src/faq.js',
article: './src/article.js',
},
output: {
filename: '[name].bundle.js',
},
optimization: {
splitChunks: {
chunks: 'all'
},
La configuración realizada para SplitChunksPlugin en este caso puede ser ideal para diversos
tipos de proyecto, pues hace diversos bundles con un criterio bastante estándar. Básicamente
estamos indicando que trocee todo lo que pueda, creando por una parte los bundles con
nuestro propio código dividido por secciones o puntos de entrada, y por otro los bundles de
terceros (los vendors).
Nota: Colocar los vendors en un bundle por separado nos ofrece una ventaja interesante en
tiempo de desarrollo, ya que nos permite ahorrar mucho tiempo a la hora de producir los
bundles de la aplicación, ya que no tiene que volver a recompilar cada vez todo el código de
las librerías de terceros (que no suelen cambiar habitualmente entre compilación y
compilación). También en tiempo de ejecución, ya que igualmente no suelen cambiar los
vendors entre builds, por lo que el navegador los puede mantener cacheados y cada vez que
hagamos un deploy, nuestros usuarios no tendrán que volver a descargar todo el código de
la aplicación.
Al compilar la aplicación, Webpack nos ofrece esta salida detallando los bundles que ha
creado, así como su peso, nombres de archivos, etc.
Además puedes fijarte que para cada punto de entrada de tu aplicación te indica cuáles son los
bundles que deberías cargar, lo que aclara cómo debería ser la colocación de las etiquetas
SCRIPT y sus src.
http://desarrolloweb.com/manuales/manual-webpack.html Página 52 de 54
Manual de Webpack
Webpack nos permite una configuración bastante minuciosa para indicarle cómo queremos
que construya los bundles. Dependiendo de nuestra aplicación podemos tener diversas
alternativas de configuraciones posibles. Aquí sería escoger la que más sentido tenga para
nosotros.
optimization: {
splitChunks: {
cacheGroups: {
commons: {
name: 'commons',
chunks: 'initial',
minChunks: 2
},
Para cada punto de entrada tendremos que cargar el archivo commons.bundle.js y su archivo
con el código particular de esa sección.
http://desarrolloweb.com/manuales/manual-webpack.html Página 53 de 54
Manual de Webpack
hemos podido aligerar el código de todo lo que sólo se usa en una (y sólo una) sección en
concreto. No obstante, ya resulta una ventaja importante con respecto a la alternativa de no
hacer ningún troceado de código.
Conclusión
Hemos podido conocer una de las alternativas más importantes que nos ofrece Webpack para
la optimización del código de las aplicaciones. Nos permite usar un conjunto de bundles que
contienen el código de cada sección por separado, aligerando mucho el peso que necesitamos
descargar y la cantidad de código a procesar, en el primer renderizado de la aplicación. Gracias
al troceado del código Javascript podrás mejorar la experiencia de usuario.
Obviamente, cuando accedemos a nuestra página, tenemos que cargar solamente los bundles
que esa determinada sección usada como punto de entrada necesita. Retrasando la carga de los
scripts y componentes que no se van a usar hasta más adelante. Todos los bundles que se
necesiten a continuación se tendrán que incluir por carga perezosa (lazy load) y para ello
usarás las prácticas habituales de Javascript nativo, o bien de tu framework o librería si es que
te ofrecen una manera específica de realizarlo.
Para traerte por lazy load los bundles necesarios para las nuevas vistas o secciones a las que
acceda el usuario generalmente usarás el estándar de los "dinamic imports" (imports
dinámicos de ES6), que es algo que ya está disponible en la mayoría de los navegadores
comunes (y cuando no esté, tendrás que usar los correspondientes polyfills).
http://desarrolloweb.com/manuales/manual-webpack.html Página 54 de 54