Bundling con la extensión Web Essentials para Visual Studio

Hace tiempo estuve contando la forma de trabajar con Bundles en ASP.NET, donde el back-end es el encargado de unir y comprimir los ficheros seleccionados. Cuando tenemos aplicaciones muy grandes con muchos scripts específicos para determinadas vistas, no es muy viable registrar cada uno de ellos en la configuración de Bundles en el Global.asax. Gracias a la extensión Web Essentials podemos realizar estas acciones en tiempo de desarrollo.

Recordando un poco el por qué hacemos esto, el objetivo principal es reducir el número de peticiones (gracias al bundling) y, ademas, que el contenido sea lo más ligero posible (gracias a la compresión/minification). Un ejemplo claro que podemos ver con demasiada frecuencia es el siguiente:

<!DOCTYPE html>
<html>
<head>
    <title>Bundling Web Essentials</title>
</head>
    <body>
        <script src="scripts/aScript.js"></script>
        <script src="scripts/bScript.js"></script>
        <script src="scripts/cScript.js"></script>
    </body>
</html>

Cuando instalamos esta extensión, tenemos un submenú adicional en el menú contextual de Visual Studio donde podemos elegir lo siguiente:

Web Essentials Create JavaScript bundle file

Lo primero que necesitamos definir es el nombre del bundle:

bundle name

Una vez aceptemos creará un conjunto de archivos:

Bundle configuration

El que encapsula a todos ellos, se trata de un archivo XML, el cual contiene la configuración del mismo (minify, runOnBuild, output) y el nombre de los archivos que componen el bundle, además de su orden:

<?xml version="1.0" encoding="utf-8"?>
<bundle minify="true" runOnBuild="true" output="myBundle.js">
  <!--The order of the <file> elements determines the order of them when bundled.-->
  <file>/scripts/aScript.js</file>
  <file>/scripts/bScript.js</file>
  <file>/scripts/cScript.js</file>
</bundle>

En el archivo indicado como output (myBundle.js) se puede visualizar el resultado de la unión de todos los archivos involucrados, donde se puede apreciar un aspecto similar al siguiente:

///#source 1 1 /scripts/aScript.js
var MyScripts = MyScripts || function () {
    var helloWorld = function () {
        alert("Hello World!");
    };
    return {
        sayHello: helloWorld
    };
}();
///#source 1 1 /scripts/bScript.js
var MyCompany = MyCompany || function () {
    var clickHandler = function () {
        MyScripts.sayHello();
    };
    return {
        click: clickHandler
    };
}();
///#source 1 1 /scripts/cScript.js
window.onload = function () {
    document.getElementById('btnAction').addEventListener('click', function () {
        MyCompany.click();
    });
};

Por último, tenemos el resultado final en myBundle.min.js, el cual es que debemos asociar con nuestra vista, y su correspondiente source map.

Llegados a este punto, ya podemos modificar nuestro código de la siguiente manera:

<!DOCTYPE html>
<html>
<head>
    <title>Bundling Web Essentials</title>
</head>
<body>
    <input id="btnAction" type="button" value="Click">
    <script src="scripts/myBundle.js"></script>
</body>
</html>

Además, gracias al source map generado, podemos disfrutar también de la depuración de estos scripts en producción:

myBundle.js source map

¡Saludos!