Hola gente de EDteam, soy su amigo y docente digital Jonathan MirCha, y en este artículo quiero hablarles de Webpack.
¿Qué es Webpack?
Es un empaquetador de archivos para aplicaciones JavaScript modernas, totalmente configurable y a diferencia de los Task Runners (como Grunt y Gulp) donde los procesos se gestionan de forma separada, en webpack, se conoce el origen y todo se compila en un único archivo.
Crea una gráfica de todas las dependencias de la aplicación. Tiene un archivo de configuración, denominado webpack.config.js, donde se define todo el proceso de construcción en un objeto JS.
Webpack tiene 4 conceptos clave:
- Entry: Indica cuál es el punto(s) de entrada.
- Output: Indica cuál es el punto(s) de salida.
- Loaders: Realizan transformaciones en los archivos.
- Plugins: Realizan acciones en los archivos.
Aprende más sobre webpack:
Sin archivo de configuración
Desde la versión 4 una de las cosas en las que se han esforzado los desarrolladores de webpack, es facilitarnos el proceso de configuración de la herramienta e incluso desde esta versión ya puedes comenzar a trabajar sin un archivo de configuración, sigue estos sencillos pasos:
Crea un nuevo directorio y colócate en el:
1mkdir webpack-starter-kit && cd webpack-starter-kit
Inicia un proyecto Node:
1npm init
Instala webpack y su cli:
1npm i -D webpack webpack-cli
En el package.json agrega el siguiente comando:
1"scripts" : { 2 "build" : "webpack" 3}
Ejecuta el comando:
1npm run build
El comando arrojará un error:
1ERROR in Entry module not found: Error: Can't resolve './src' in '~/webpack-starter-kit'
Webpack está buscando un punto de entrada en ./src 😱😱😱¡¡¡ Sin Archivo de configuración !!!
A partir de la versión 4 no es necesario definir el punto de entrada, tomará ./src/index.js como valor predeterminado 🤓.
En versiones anteriores, el punto de entrada debe definirse dentro del archivo de configuración denominado webpack.config.js.
Sigamos con nuestro ejemplo:
Crea el archivo ./src/index.js y escribe:
1console.log('Hola mundo sin configuración con Webpack')
Ejecuta nuevamente el comando build y webpack en automático nos habrá generado el archivo de salida ./dist/main,js 😱😱😱
Modo de producción y desarrollo
En webpack un patrón común es tener 2 archivos de configuración uno para las tareas de desarrollo y otro para las de producción.
Mientras que para proyectos grandes aún se pueden necesitar 2 archivos, en proyectos pequeños , es posible especificar el tipo de configuración en una sola línea de configuración.
Webpack 4 introduce el modo de producción y el modo de desarrollo.
De hecho cuando corrimos el comando build la terminal nos mando un mensaje de advertencia:
1WARNING in configuration 2The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment. 3You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
La opción 'modo' no se ha configurado. Establezca la opción 'modo' en 'desarrollo' o 'producción' para habilitar los valores predeterminados para este entorno.
Vamos a crear un comando para cada ambiente:
1"scripts" : { 2 "dev" : "webpack --mode development" , 3 "build" : "webpack --mode production" 4}
Ejecutemos ambos comandos y miremos el archivo ./dist/main.js después de ejecutarlos:
npm run dev
generará un archivo indentado y con comentarios.npm run build
generará un archivo minificado y sin comentarios.
Modificando puntos de entrada y salida predeterminados:
1"scripts": { 2 "dev": "webpack --mode development ./foo/src/index.js --output ./foo/main.js", 3 "build": "webpack --mode production ./foo/src/index.js --output ./foo/main.js" 4}
Transpilando Javascript ES6 con Babel
Webpack por sí sólo no sabe como transpilar código ES6, pero tiene un loader que lo hace.
Instala babel-loader y sus dependencias:
1npm i -D babel-loader babel-core babel-preset-env
Ahora crea el archivo .babelrc con el siguiente código:
1{ 2 "presets": [ 3 "env" 4 ] 5}
En este punto tenemos 2 opciones para configurar babel-loader:
- Sin archivo de configuración.
- Con archivo de configuración.
Escribe el siguiente código en tu archivo ./src/index.js
1const arr = [1, 2, 3], 2 codeES6 = () => console.log(...arr) 3 4window.codeES6 = codeES6 5 6window.codeES6()
Sin archivo de configuración
Se agrega la opción --module-bind con el valor js=babel.loader:
1"scripts": { 2 "dev-babel": "webpack --mode development --module-bind js=babel-loader", 3 "build-babel": "webpack --mode production --module-bind js=babel-loader" 4 }
Ejecutemos ambos comandos y miremos el archivo ./dist/main.js después de ejecutarlos:
npm run dev-babel
transpiló el archivo con sintaxis ES6 a ES5 indentado y con comentarios.npm run build-babel
transpiló el archivo con sintaxis ES6 a ES5 minificado y sin comentarios.
Con archivo de configuración.
Crea el archivo webpack.config.js y escribe el siguiente código:
1module.exports = { 2 module: { 3 rules: [ 4 { 5 test: /\.js$/, 6 exclude: /node_modules/, 7 use: { 8 loader: 'babel-loader' 9 } 10 } 11 ] 12 } 13};
Ejecutemos los comandos dev y build y miremos el archivo ./dist/main.js después de ejecutarlos:
npm run dev
transpiló el archivo con sintaxis ES6 a ES5 indentado y con comentarios, gracias a la configuración del archivo webpack.config.js.npm run build
transpiló el archivo con sintaxis ES6 a ES5 minificado y sin comentarios, gracias a la configuración del archivo webpack.config.js.
Inyección de JS en HTML
Para inyectar el código dinámico que genera webpack en los archivos HTML, necesita 2 dependencias : html-webpack-plugin y html-loader.
Instala las dependencias:
1npm i -D html-webpack-plugin html-loader
Agrega la siguiente regla al archivo webpack.config.js:
1const HtmlWebPackPlugin = require("html-webpack-plugin"); 2 3module.exports = { 4 module: { 5 rules: [ 6 { 7 test: /\.js$/, 8 exclude: /node_modules/, 9 use: { 10 loader: 'babel-loader' 11 } 12 }, 13 { 14 test: /\.html$/, 15 use: [ 16 { 17 loader: 'html-loader', 18 options: { minimize: true } 19 } 20 ] 21 } 22 ] 23 }, 24 plugins: [ 25 new HtmlWebPackPlugin({ 26 template: './src/index.html', 27 filename: './index.html' 28 }) 29 ] 30};
Ahora crea el archivo ./src/index.html:
1<!DOCTYPE html> 2<html lang="es"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Webpack</title> 7</head> 8<body> 9 <div id="app"></div> 10</body> 11</html>
Ejecutemos los comandos dev
o build
y miremos el archivo ./dist/index.html
después de ejecutarlos.
No es necesario incluir el JavaScript dentro del archivo HTML, webpack lo ha inyectado automáticamente y ha minificado el código 😎.
Extracción de CSS
Webpack por sí sólo no sabe como extraer código CSS en un archivo externp, pero tiene un loader y un plugin que lo hace.
Instala las dependencias:
1npm i -D mini-css-extract-plugin css-loader
Agrega la siguiente regla al archivo webpack.config.js:
1const HtmlWebPackPlugin = require('html-webpack-plugin'), 2 MiniCssExtractPlugin = require('mini-css-extract-plugin'); 3 4module.exports = { 5 module: { 6 rules: [ 7 { 8 test: /\.js$/, 9 exclude: /node_modules/, 10 use: { 11 loader: 'babel-loader' 12 } 13 }, 14 { 15 test: /\.html$/, 16 use: [ 17 { 18 loader: 'html-loader', 19 options: { minimize: true } 20 } 21 ] 22 }, 23 { 24 test: /\.css$/, 25 use: [MiniCssExtractPlugin.loader, 'css-loader'] 26 } 27 ] 28 }, 29 plugins: [ 30 new HtmlWebPackPlugin({ 31 template: './src/index.html', 32 filename: './index.html' 33 }), 34 new MiniCssExtractPlugin({ 35 filename: '[name].css', 36 chunkFilename: '[id].css' 37 }) 38 ] 39};
Ahora crea el archivo ./src/style.css con algo de código:
1html { 2 box-sizing: border-box; 3 margin: 0; 4 padding: 0; 5 font-family: sans-serif; 6 font-size: 16px; 7 color: #8DD6F9; 8 background-color: #2B3A42; 9}
Ahora importamos los estilos desde el punto de entrada, el archivo ./src/index.js:
1import style from './style.css'
Ejecutemos los comandos dev o build y miremos el archivo ./dist/index.html después de ejecutarlos.
No es necesario incluir el CSS dentro del archivo HTML, webpack lo ha inyectado automáticamente y ha creado el archivo de estilos main.css 😎.
Servidor Web de Desarrollo
No es muy óptimo estar ejecutando el comando dev cada vez que hacemos un cambio en nuestra aplicación lo ideal es configurar un servidor web de prueba que en automático recompile nuestro código y recargue el navegador.
Webpack, cuenta con su propio servido de desarrollo.
Instala la dependencia:
1npm i -D webpack-dev-server
Agregamos el comando start a nuestro package.json:
1"scripts": { 2 "start": "webpack-dev-server --mode development --open" 3}
Al ejecutarlo, webpack abrirá la aplicación en una ventana del navegador.
1npm start
Como verás ahora es mucho más facil comenzar a desarrollar aplicaciones con flujos de trabajo modernos y herramientas como webpack, recuerda que en EDteam tenemos un curso sobre esta herramienta y otro donde desarrollamos un proyecto 100% práctico, ambos cursos forman parte de una gran especialidad en Frontend que tenemos en EDteam, a continuación te dejo los enlaces de los cursos:
Se despide su amigo y docente digital Jonathan MirCha, sean felices, hasta siempre, nos leemos la próxima semana. Bye.