Ordenar los bundles de ASP.Net MVC

Si alguna vez habeis intentado hacer un gran proyecto con ASP.Net MVC, vereis que utilizar los bundles para incluir el código tanto javascript (ScriptBundle) como css (StyleBundle) en nuestra página es muy útil ya que nos ofrece diferentes formas de tratar los archivos a incluir, uno de mis favoritos es unificar todo el bundle compilado y minimizado. Todo parece un camino de rosas, poder agrupar todos nuestros css y javascript en una sola linea incluyendo archivos o directorios.

No todo es maravilloso y aunque Microsoft suele hacer las cosas bastante bien, siempre se deja algún extraño por el camino. En este caso el extraño es el orden en que se cargan los archivos en la página usando Bundles. Cuando tenemos multitud de archivos javascript o css por ejemplo, se da el caso en que no todos los archivos se cargan en el orden en que lo incluimos. No se si tiene algo que ver mezclar inclusiones por archivos y directorios a la vez, pero no mantiene el orden igual. Es una locura, puesto que aparentemente todo sigue un orden, pero cuando tenemos una docena de archivos javascript o css, a veces hay alguno que se descoloca. A mi me pasó con backbone y underscore, que como sabreis quien haya trabajado con estas librerias, backbone requiere de underscore y si no esta incluido previamente provoca un error.

Lo primero que tenemos que hacer es crear una nueva clase para hacer el IBundleOrderer.OrderFiles que ordene los bundles, en nuestro caso, realmente no queremos que ordene sino que los muestre en el orden en que los escribimos. La clase en cuestión sería:

public class UserDefinedBundleOrderer : IBundleOrderer {
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files) {
        return files;
    }
}

Una vez tengamos nuestra clase IBundleOrderer, solo deberemos indicar a nuestro bundle, bien sea un ScriptBundle, un StyleBundle o un Bundle genérico, que utilice como Orderer nuestra clase que se encarga de la "ordenación" o en este caso, dejar las cosas como están. Lo haremos con el Bundle.Orderer como se muestra en el ejemplo:

myBundle.Orderer = new UserDefinedBundleOrderer();

Y ahora os dejo un ejemplo real sacado directamente de un proyecto propio. Así quedaría todo el archivo completo. Podemos ver como el BundleConfig donde definimos la carga de Bundles, tenemos un StyleBundle que cargará nuestros css, mientras que el ScriptBundle cargará nuestras librerías javascript y es a esta clase donde aplicamos nuestra clase para la ordenación de Bundles.

using System.Collections.Generic;
using System.IO;
using System.Web;
using System.Web.Optimization;

namespace MyWeb {
  public class BundleConfig {
    public static void RegisterBundles(BundleCollection bundles) {
      BundleTable.EnableOptimizations = true;

      bundles.Add(new StyleBundle("~/assets/css").Include(
        "~/Content/css/dark-hive/jquery-ui.css",
        "~/Content/css/bootstrap.css",
        "~/Content/css/site.css"
      ));

      ScriptBundle libs = new ScriptBundle("~/assets/libs");
      libs.Orderer = new UserDefinedBundleOrderer();
      libs.Include(
        "~/Scripts/libs/jquery-1.8.2.js",
        "~/Scripts/libs/jquery-ui-1.8.24.js",
        "~/Scripts/libs/jquery-ui.datepicker.es.js", 
        "~/Scripts/libs/underscore-1.4.1.js",
        "~/Scripts/libs/backbone-0.9.2.js",

      bundles.Add(libs);
    }
  }

  public class UserDefinedBundleOrderer : IBundleOrderer {
    public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files) {
      return files;
    }
  }
}

Espero que os sirva de ayuda.

4 comentarios en “Ordenar los bundles de ASP.Net MVC

  1. Pingback: Bitacoras.com
  2. Buenas noches.

    Me sale error al implementar la clase UserDefinedBundleOrderer el error el lo siguiente:

    Error 3 'LK.Web.UserDefinedBundleOrderer' no implementa el miembro de interfaz 'System.Web.Optimization.IBundleOrderer.OrderFiles(System.Web.Optimization.BundleContext, System.Collections.Generic.IEnumerable)' D:\PROYECTO 2016\LK\LK\LK.Web\App_Start\BundleConfig.cs 8 18 LK.Web

    espero me pueda ayudar, gracias.

  3. Hola Isaias.

    Cuando lo esribií se implementaba como en el ejemplo. Ahora con las nuevas versiones de .Net tienes que cambiar por

    Te quedaría algo tal que:

    public class UserDefinedBundleOrderer : IBundleOrderer {
        public virtual IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files) {
        return files;
      }
    }
    

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *