Para crear proyectos eficientes y bien optimizados, es esencial aprender a integrar HTML con Webpack. Este proceso permite preparar y gestionar adecuadamente nuestros archivos HTML para producción. A continuación, te guío paso a paso sobre cómo lograrlo.
¿Qué necesitas para empezar?
Instalar HTML-webpack-plugin: Este plugin es fundamental para la configuración de Webpack, ya que mejora el manejo de archivos HTML en nuestro proyecto.
Instalación del plugin:
npminstall html-webpack-plugin --save-dev
Configuración en el archivo webpack.config.js: Necesitamos modificar este archivo para incluir el plugin que acabamos de instalar. La idea es que Webpack procese nuestros archivos HTML correctamente.
Añadir el plugin al archivo de configuración:
constHtmlWebpackPlugin=require('html-webpack-plugin');module.exports={// otras configuracionesplugins:[newHtmlWebpackPlugin({inject:true,template:'./public/index.html',filename:'index.html',}),],};
¿Cómo preparar el archivo HTML?
Con el plugin integrado, debemos asegurarnos de que nuestro archivo HTML base esté bien configurado. Usamos un template que personalizamos y aseguramos que al compilar el proyecto, Webpack automáticamente incluya los scripts necesarios.
Cambios en el archivo index.html:
Eliminar referencias directas a scripts que serán gestionados por Webpack:
<!-- Antes --><scriptsrc="main.js"></script><!-- Después --><!-- Webpack se encargará de esto -->
¿Cómo se compila y prueba el proyecto?
Con la configuración completa, ahora compilar y probar el proyecto es sencillo. Podemos hacerlo tanto para entornos de desarrollo como de producción usando diferentes comandos de npm.
Compilar para producción:
npm run build
Este comando genera la versión optimizada para producción, incluyendo la minificación de archivos.
Compilar para desarrollo:
npm run dev
Nos ayuda a obtener una versión más legible del código, ideal para depuración.
¿Qué observar después de la compilación?
Una vez realizados los pasos anteriores y ejecutados los comandos, revisamos que:
Nuestro index.html está incluido con scripts automáticamente inyectados.
La versión de producción está minificada.
La versión de desarrollo mantiene un formato más legible para facilitar la depuración.
Con estos pasos, has configurado correctamente tu proyecto para trabajar con HTML y Webpack. ¡Continúa perfeccionando tus habilidades con CSS y preprocesadores para maximizar el potencial de tu proyecto!
HtmlWebpackPlugin
Es un plugin para inyectar javascript, css, favicons, y nos facilita la tarea de enlazar los bundles a nuestro template HTML.
Instalación
npm
npm i html-webpack-plugin -D
yarn
yarn add html-webpack-plugin -D
Al webpack config queda asi
const path =require('path')constHtmlWebpackPlugin=require('html-webpack-plugin')module.exports={mode:'production',// LE INDICO EL MODO EXPLICITAMENTEentry:'./src/index.js',// el punto de entrada de mi aplicaciónoutput:{// Esta es la salida de mi bundlepath: path.resolve(__dirname,'dist'),// resolve lo que hace es darnos la ruta absoluta de el S.O hasta nuestro archivo// para no tener conflictos entre Linux, Windows, etcfilename:'main.js',// EL NOMBRE DEL ARCHIVO FINAL,},resolve:{extensions:['.js']// LOS ARCHIVOS QUE WEBPACK VA A LEER},module:{// REGLAS PARA TRABAJAR CON WEBPACKrules:[{test:/\.m?js$/,// LEE LOS ARCHIVOS CON EXTENSION .JS,exclude:/node_modules/,// IGNORA LOS MODULOS DE LA CARPETAuse:{loader:'babel-loader'}}]},// SECCION DE PLUGINSplugins:[newHtmlWebpackPlugin({// CONFIGURACIÓN DEL PLUGINinject:true,// INYECTA EL BUNDLE AL TEMPLATE HTMLtemplate:'./public/index.html',// LA RUTA AL TEMPLATE HTMLfilename:'./index.html'// NOMBRE FINAL DEL ARCHIVO})]}
HtmlWebpackPlugin no tiene nada que ver con javascript, css ni favicons.
Muchas gracias!
++TIP++: Si lo notaron cuando se hace bundle la etiqueta <script> es insertada adentro de la etiqueta <head>... Para insertarlo al final de la etiqueta <body> se le pasa el siguiente string: 'body'.
Para los que van pasando por el curso, les recomiendo revisar la documentación de los loaders y plugins en https://www.npmjs.com/ en la medida que los van presentando en el curso, al menos para tener una referencia futura de dónde encontrar la documentación, ya que a medida que pasa el tiempo las herramientas se van actualizando y por ejemplo:
A esta fecha al descargar webpack está disponible la versión 5.36.2 , por tanto, al instalar el plugin con el comando que se muestra en el curso, se instaló la versión 5 del plugin:
npm i html-webpack-plugin -D
Pero si por alguna razón ya tenías instalado webpack en una versión anterior, ejemplo webpack 4.36, entonces debería s instalar la versión del plugin 4
npm i -D html-webpack-plugin@4
La documentación señala estas consideraciones y créanme, en la medida que participen en más proyectos, pasarán un montón de tiempo tratando de encontrar soluciones por problemas de compatibilidad de las versiones de las distintas herramientas y requerirán escudriñar la documentación.
Muy buen aporte @Jenny! Me encantó!
Respuestas a tus posibles dudas:
1. ¿Por qué añadimos este recurso (HtmlWebpackPlugin) como un constal inicio?
Porque un plugin en sí es un objeto de JavaScript. Dicho objeto tiene un método llamado apply. El método apply es llamado por el compilador de webpack para hacer su trabajo.
El plugin, al ser un objeto, debemos instanciarlo. Pero ¿Dónde vive el código para instanciar dicho objeto? Exacto, en el módulo que estamos "requiriendo" mediante require y que instalamos en esta clase.. Para comodidad, guardamos todo ese módulo en la constante HtmlWebpackPlugin. Piensa que este es el nombre de la clase a partir de la cual podremos instanciar un objeto.
.
2. ¿Por qué añadimos pluginsdespués de module?
Así lo indica la documentación de webpack. De la misma manera, indica que todos los elementos del índice/atributo pluginsdeben estar contenidos dentro de un arreglo.
.
3. ¿Por qué usamos new HtmlWebpackPlugin({objeto})?
Porque, como puse en la primera pregunta de este aporte, el plugin es un objeto. Por lo tanto con este new lo estamos instanciando. Si te lo estás preguntando, sí, el hecho de instanciarlo como un objeto nos permite utilizar el plugin, mediante diferentes objetos, para diferentes propósitos (o con diferentes configuraciones). Esto se hace instanciando diferentes objetos de la misma clase.
.
4. En el objeto que le pasamos a la instancia de HtmlWebpackPlugin, ¿De dónde salen el inject y todas las otras vainas?
Son parámetros de configuración que se le pasan al plugin. Aquí solo se usan inject, template y filename aunque hay más. Puedes encontrar todos y cada uno de ellos, así como sus posibles valores y lo que hacen en el siguiente vínculo: .
.
5. ¿Por qué eliminamos la etiqueta <script> en public/index.html y webpack lo agrega posteriormente?
En la lección 5 de este curso hablé sobre el gráfico de dependencias. Webpack lo genera para construir el bundle o empaquetamiento.
Si revisas nuestro archivo de entrada entry, que es index.js, verás que lo único que hace es colocar el html de Template.jsen el html. Para eso se guía con el "id" llamado "main" que está dentro del index.html
.
Webpack insertará dentro del html de salida el archivo JS que hayamos configurado de salida. En este caso, recuerda que configuramos que la salida fuera main.js. Por eso, cuando genera el nuevo index.html, ya viene con este insertado.
.
De hecho puedes hacer la prueba cambiando el nombre de la salida principal (archivo JS) y verás que siempre lo va a insertar, aun cuando hagas que la salida se llame patitos.js.
.
Es por esto que se elimina la etiqueta de <script> en el html original, ya que podría traernos problemas después. De hecho, si no la eliminas manualmente como lo hicimos en esta lección, es muy probable que tengas inconvenientes o errores, ya que seguirá apareciendo en el html de salida. De hecho, si no eliminas la etiqueta, mira cómo se "duplica" la importación en el siguiente código que me dio de salida:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="stylesheet" href="../src/styles/main.css"><title>JSPortfolio</title><script defer src="main.js"></script></head>// En el archivo de configuraciones de webpack puedes cambiar a que la salida sea "patito.js", si es que quieres probar<body><div id="main"></div><script type="module" src="../src//index.js"></script></body></html>
Excelente miguel, como todas las clases. Me liberas de muchas dudas
** HtmlWebpackPlugin**
Webpack reference
Github reference
Cabe mencionar que el profesor, por practicidad, esta comentando opciones que son determinadas por default.
Por comentario adicional, este plugin nos permite personalizar la creación de nuestros archivos HTML con la intención de ser servidos como bundles, los cuales, serán instancias de estandarización de archivo útiles plantillass lodash
Gran aporte/comentario @Emmanuel!
Gracias!
MY NOTES FOR HTML IN WEBPACK
Como vamos a preparar nuestro proyecto para que webpack pueda entenderlo y prepararlo
Lo primero que hay que hacer es instalar el plugin que nos permite trabajar webpack con html
npm i html-webpack-plugin -D
Después añadimos esta dependencia a la configuración de webpack
//traemos esta dependencia que la instalamos con un comando de npm previamenteconstHtmlWebpackPlugin=require('html-webpack-plugin');plugins:[//hacemos una instancia de lo que definimos en el inicio del archivo// le anadimos por parametro un objeto donde vamos a tener las //configuraciones que le vamos anadir a nuestro pluginnewHtmlWebpackPlugin({//inyecta el bundle al template htmlinject:true,//la ruta al template htmltemplate:'./public/index.html',//nombre final del archivofilename: filename:'./index.html'})]
Eliminamos el script de nuestro html porque webpack se encargara de insertar el script que compila
Una vez compilamos nuestro archivo de webpack se insertara el main.js en nuetsro html
agregamos otro script para ejecutar mas facil nuestros comando
"scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --mode production","dev":"webpack --mode development"},
HTML en Webpack
Para poder preparar HTML para usarlo con Webpack tendremos que instalar el plugin de html-webpack-plugin. El comando para instalarlo es:
npm i html-webpack-plugin -D
Con este plugin podremos trabajar con html, poder identificarlo y generar un nuevo recurso basado en esto mismo.
Tenemos que configurar el plugin para que sirva dentro de webpack.
plugins:[ new HtmlWebpackPlugin({ inject:true, template: './public/index.html', filename: './index.html'
})
]}
este profesor entra en mi top 3 de platzi
SI, realmente es muy bueno.👌
¿Quién esta en tu top 1 y 2?
No me esta funcionando a la hora de correr el comando npm run build desde la clase pasada, me sale que compila todo de manera correcta (es decir sin ningún error) pero, no me arroja el mismo resultado que al profesor. No se me creo el archivo de index.html en la carpeta de dist ni tampoco se agregan mas código en mi main.js. A alguien mas le sucede lo mismo? Y si logro solucionar, como lo hizo?
Puedes compartir tu repositorio por favor?
Retrocedí las clases para hacer todo de vuelta por si cometí algún error, cuando llegue nuevamente aquí y si ocurre lo mismo te comparto sin problemas, muchas gracias por tu ayuda Hector.
P.D.: Me esta doliendo bastante este curso. 😂
Para los que tienen el problema de que no se les crea el index.html; revisen si han colocado module.export en lugar de module.exports (en plural, 's' al final); fue lo que me ocurrió a mí.
Si no, pueden hacer lo que yo para debuggear... Solo hice un commit del projecto con problemas, luego copie todo el contenido del archivo webpack.config.js que está acá en la sección de recursos, y lo pegué en el archivo webpack.config.js de mi proyecto. Con eso funcionó. Luego como hice un commit antes y otro después de la solución. Corrí el comando:
git diff commit1 commit2
Y pude ver que el problema era que tenía module.export en lugar de module.exports (con 's' al final)
Espero que esto sea útil ;)
Que pasaría si tengo más archivos HTML, ¿cómo hago la configuración o Webpack los configura todos por defecto?
Hola Jesus Moo, estas en lo correcto debes de configurar el archivo webpack.config.js si vas añadir mas archivos html, te dejo la documentación para mas detalles :aqui
Nunca se me generó el index.html.... seguí con mi vida.
Alerta de deuda tecnica !!
Ya logré solucionarlo, solo copie todo el contenido del archivo webpack.config.js que está acá en la sección de recursos, y lo pegué en mi archivo. Luego como hice 1 commit antes y otro después de la solución. Corrí el comando:
git diff commit1 commit2
Y pude ver que el problema era que tenía module.export en lugar de module.exports (con 's' al final)
Hola.
A alguien le ha pasado que el index.html no se genera utilizando HtmlWebpackPlugin
plugins: [
new HtmlWebpackPlugin({
inject: "body",
template: './public/index.html',
filename: './index.html',
})
]
Cuando se ejecuta
npm run build
No se genera ningún error, pero solo genera el archivo main.js.
Hola!
Creo que es por el inject, qué pasa si lo quitas?
Tal vez el nombre del archivo no es el correcto, me pasaba lo mismo y tenía el archivo webpack.configs.js y debía ser webpack.config.js
Para fijar el título en el HTML desde el plugin, se puede hacer de la siguiente manera:
Dejo mi aporte de como hice para exportar todos mis archivos HTML que estan dentro de ./public/html
Basicamente use la libreria fs para filtrar los archivos que terminen en .html y por cada archivo encontrado cree una nueva instancia de HtmlWebpackPlugin
HTML en Webpack
"build": "webpack --mode production" para modo de producción y minificado
"dev": "webpack --mode development" para modo de desarrollo y no minificado
Al igual que con cualquier otro lenguaje, Webpack necesita un loader para trabajar con HTML.
Para instalarlo se usa el comando npm install html-webpack-plugin -D.
Una vez instalado hay que añadirlo a la configuración de Webpack.
Primero creamos una constante al inicio con el plugin que descargamos.
Luego creamos la propiedad plugins, que es un arreglo y ahí creamos una nueva instancia del plugin.
Esta instancia recibe un objeto de configuración con las propiedades inject que indica si se va a hacer inserción de elementos; template, que es el archivo que va a procesar y filename que es el archivo resultante.
Ahora hay que hacer algunos cambios al archivo HTML. Lo primero es eliminar la etiqueta donde consume el script, ya que Webpack se encargará de ello.
Ahora sí que no sé que hacer 😩
Compañeros alguien que me ayude a entender por qué despues de correr la dependencia de Producción no me crea el archivo index.html minimizado???
Gracias por la ayuda!!
Hola jefer, seguro que es algún pequeño detalle en los ficheros que retocamos, el webpack.config.js y el index.html.
Te copio mis entradas a ver si hay alguna diferencia con las tuyas.
1.- En webpack.config.js añadir:
const HtmlWebpackPlugin = require('html-webpack-plugin');