ASP.NET MVC: orden de configuración del paquete

84

Estoy tratando de usar una configuración regional específica (es-CL) en mi aplicación ASP.NET MVC 5. Tengo lo siguiente:

  1. Se cambió web.config uicultura y cultura a "es-CL"
  2. Instaló los paquetes Globalize y jQuery.Validation.Globalize
  3. Cambié el idioma predeterminado en mis vistas: <html lang="es-cl">
  4. Se creó un nuevo paquete y se incluyó en las vistas correspondientes.

En BundleConfig.cs :

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
    .Include("~/Scripts/jquery.validate.js")
    .Include("~/Scripts/jquery.validate.unobtrusive.js"));

bundles.Add(new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js"));

En las vistas apropiadas:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/globalization")
}

Sin embargo, el código fuente generado es el siguiente:

<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>

<script src="/Scripts/jquery.validate.globalize.js"></script>
<script src="/Scripts/globalize/globalize.js"></script>
<script src="/Scripts/globalize/cultures/globalize.culture.es-CL.js"></script>

Tenga en cuenta que el script jquery.validate.globalize.js se está cargando antes de globalize.js , que no es lo que quiero.

¿Por qué está pasando esto? ¿Es posible confiar en el orden de inclusión en un solo paquete, o me veo obligado a poner este único script en un paquete diferente y especificarlo en mi vista?

Leonardo Herrera
fuente
1
Eche un vistazo a esta pregunta stackoverflow.com/questions/11979718/…
Paul McCowat
@PaulMcCowat sí, pero todavía no estoy usando las versiones minificadas. Estoy usando Microsoft.AspNet.Web.Optimizations 1.1.0.
Leonardo Herrera
@LeonardoHerrera Creo que es como Chris mencionó en sus comentarios, que los archivos conocidos se mueven a un orden especificado por el paquete ... pero no puedo estar seguro ya que no sé cuáles son esos archivos, lo que llevó me pregunte . Me interesaría saber si usar IBundleOrderer funciona para usted, ya que especificar el pedido no lo hizo.
MikeSmithDev
mire la respuesta de @Softlion en [este enlace] [1] [1]: stackoverflow.com/questions/11979718/…
Omid-RH
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }parece haber resuelto el problema de la carga de mis scripts fuera de orden ....
petrosmm

Respuestas:

103

De forma predeterminada, el orden de agrupación es alfabético para los nombres con comodines (como se indica en los comentarios). Sin embargo, también ordena en función de lo que cree que es su árbol de dependencia, y los jQueryscripts parecen colocarse en la parte superior. Necesita crear un objeto que implemente IBundleOrder:

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

Esto evita el pedido predeterminado. Ahora para usarlo:

var bundle = new ScriptBundle("~/bundles/globalization")
    .Include("~/Scripts/globalize/globalize.js")
    .Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
    .Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new NonOrderingBundleOrderer();

bundles.Add(bundle);

ref: http://stevescodingblog.co.uk/changing-the-ordering-for-single-bundles-in-asp-net-4/

Para leer más, una respuesta a la pregunta de MikeSmithDev proporciona más información sobre el orden predeterminado para las bibliotecas de scripts populares:

Ordenar archivos dentro de un paquete: ¿Cuáles son las bibliotecas conocidas?

Señor épico
fuente
No para ser quisquilloso, pero "por defecto, el orden de agrupación es alfabético" es cierto cuando usas cosas como comodines ... cuando especificas el orden, como él lo ha hecho, debería usar su orden. Solo puedo asumir que el empaquetador se mueve alrededor de tipos de archivos conocidos e ignora su orden.
MikeSmithDev
Parece que el empaquetador también ordena utilizando cierta lógica sobre dependencias. Cree que jquery.validate.globalize.jses necesario para los otros dos. De la referencia: "[El empaquetador] incluso pondrá archivos javascript de framework conocidos primero en el paquete automáticamente, como jQuery o scripts de Prototype, para asegurarse de que se ejecuten antes de que se ejecute su propio código que usa sus tipos"
Mister Epic
3
El orden específico es: jquery.js jquery-min.js jquery- * jquery-ui * jquery.ui * jquery.unobtrusive * jquery.validate * modernizr- * dojo. * Mootools-core * mootools- * prototype.js prototype- * scriptaculous- * ext.js ext- *
ravndal
6
aquí es donde la programación no es divertida. ¿Por qué VS hace esto complicado?
Jaider
5
El hecho de que esto exista me sorprende con lo estúpido que es. Realmente ... ¿el empaquetador sabe mejor cómo ordenar mis dependencias mejor que yo las escribí? Gulp.js (o incluso Grunt) FTW!
John Culviner
30

En la última versión de MVC 5 (al 27 de octubre de 2014), debería usar esta clase en su lugar:

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

Y crea el paquete como la otra respuesta:

var bundle = new ScriptBundle("~/bundles/globalization")
.Include("~/Scripts/globalize/globalize.js")
.Include("~/Scripts/globalize/cultures/globalize.culture.es-CL.js")
.Include("~/Scripts/jquery.validate.globalize.js");

bundle.Orderer = new AsIsBundleOrderer();

bundles.Add(bundle);
Sebastián Rojas
fuente
¿Dónde puedo encontrar esta información? ¿Puede proporcionar un enlace por favor?
PussInBoots
Intento usar el método de la respuesta actual para esta pregunta, pero encontré mi selkf con un error en ASP.NET MVC 5, así que verifiqué la interfaz IBundleOrderer e hice los cambios
Sebastián Rojas
No hay propiedad de ordenante. Estoy usando MVC 5.2.x
Legends
1
Solo lo pruebo con MVC 5.2.3 y tehres es la Propiedad del Ordenador.
Sebastián Rojas
28

Para reducir los códigos durante la creación de paquetes, le sugiero que cree un método de extensión.

Requerir clases de infraestructura:

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


static class BundleExtentions
{
    public static Bundle NonOrdering(this Bundle bundle)
    {
        bundle.Orderer=new NonOrderingBundleOrderer();
        return bundle;
    }
}

Ahora simplemente utilícelo así:

Todo en un comando 😎

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
               .NonOrdering()
               .Include(
                    "~/Scripts/globalize/globalize.js",
                    "~/Scripts/globalize/cultures/globalize.culture.es-CL.js",
                    //...
                );
RAM
fuente
1
¡Buena forma de pensar!
Aruna