HTML Webpack Plugin: Inyectar bundles en el HTML

  • Por
Inyectar con Webpack los correspondientes scripts, y otros elementos, en un archivo HTML generado, para instalar el contenido de tus bundles en el proyecto, con HTML Webpack Plugin.

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.

Instalación de HTML Webpack Plugin

Instalamos el plugin de webpack para inyectar el script generado en el HTML.

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.

const HtmlWebpackPlugin = require('html-webpack-plugin');

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.

Obviamente, solamente con esta configuración seguramente no se adapte a nuestras necesidades, pero el plugin ya realizará un comportamiento. Simplemente generará un archivo llamado index.html en la carpeta "dist".

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>
  <script type="text/javascript" src="main.js"></script></body>
</html>

Opciones de HTML Webpack Plugin

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.

  • title: Para indicar el título del archivo HTML generado.
  • filename: Para indicar el nombre del archivo generado.
  • template: permite colocar un archivo HTML como template para generar a partir de él nuestro código HTML resultante.
  • templateParameters: Con esta configuración podemos definir datos que enviar al template. Colocaremos los datos en notación de objeto Javascript.
Nota: Si usamos la configuración "template" no se cargará automáticamente el título que definas en la opción "title". Puedes enviar el título y cualquier otro dato, del template al HTML generado, por medio de los templateParameters.

Existen muchas otras configuraciones, que puedes ver en la documentación de HTML Webpack Plugin. Ahora puedes ver un ejemplo sencillo de uso.

plugins: [
    new HtmlWebpackPlugin({  
      filename: 'index.html',
      template: 'src/index.html',
      templateParameters: {
        titulo: 'Manual de Webpack en Desarrolloweb',
        encabezamiento: 'Aprendo Webpack en DesarrolloWeb.com',
      }
    })
  ]

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">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title><%= titulo %></title>
</head>
<body>
  <h1><%= encabezamiento%></h1>
</body>
</html>

Al ejecutarse ahora Webpack obtendremos este código HTML generado.

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Manual de Webpack en Desarrolloweb</title>
</head>
<body>
  <h1>Aprendo Webpack en DesarrolloWeb.com</h1>
<script type="text/javascript" src="main.js"></script></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:

  • main.js: el bundle principal
  • index.html: el archivo html generado con el conocimiento de este artículo.

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.

Hash en el nombre de archivo del bundle

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:

<script type="text/javascript" src="main.js?9992c496ace80a68b76e"></script>

Producir varios archivos HTML

Si tenemos la necesidad de producir varios archivos de HTML como salida, en output, podemos hacerlo fácilmente con la instanciación de varios objetos del plugin HTML Webpack Plugin, colocados en el array "plugins" del webpack.config.js. Cada una de las instanciaciones generará un archivo. La única cosa es que tendremos que pasarle a cada instanciación un nombre de archivo distinto en la opción "filename", puesto que si no se hace así, se sobreescribirán las distintas salidas en el mismo "index.html".

El código nos podría quedar más o menos como este:

plugins: [
  new HtmlWebpackPlugin({  
    filename: 'index.html',
    template: 'src/index.html',
    hash: true,
    templateParameters: {
      titulo: 'Manual de Webpack en Desarrolloweb',
      encabezamiento: 'Aprendo Webpack en DesarrolloWeb.com',
    }
  }),
  new HtmlWebpackPlugin({
    filename: 'standar.html'
  }),
  new HtmlWebpackPlugin({
    filename: 'index2.html',
    template: 'src/index.html',
    templateParameters: {
      titulo: 'Curso de Webpack de EscuelaIT',
      encabezamiento: 'Aprendo mucho más Webpack en Escuela.it',
    }
  }),
  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.