ASP.NET MVC - kolejność konfiguracji pakietu

84

Próbuję użyć określonych ustawień regionalnych (es-CL) w mojej aplikacji ASP.NET MVC 5. Mam następujące rzeczy:

  1. Zmieniono kulturę i kulturę pliku web.config na „es-CL”
  2. Zainstalowano pakiety Globalize i jQuery.Validation.Globalize
  3. Zmieniono domyślny język w moich widokach: <html lang="es-cl">
  4. Utworzono nowy pakiet i uwzględniono go w odpowiednich widokach.

W 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"));

W odpowiednich widokach:

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

Jednak wygenerowany kod źródłowy jest następujący:

<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>

Zwróć uwagę, że skrypt jquery.validate.globalize.js jest ładowany przed globalize.js , co nie jest tym, czego chcę.

Dlaczego to się dzieje? Czy można polegać na kolejności dołączania w pojedynczym pakiecie, czy też jestem zmuszony umieścić ten pojedynczy skrypt w innym pakiecie i określić go w moim widoku?

Leonardo Herrera
źródło
1
Spójrz na to pytanie stackoverflow.com/questions/11979718/…
Paul McCowat
@PaulMcCowat tak, ale nie używam jeszcze wersji zminimalizowanych. Używam Microsoft.AspNet.Web.Optimizations 1.1.0.
Leonardo Herrera,
@LeonardoHerrera Wydaje mi się, że to tak, jak Chris wspomniał w swoich komentarzach, że znane pliki są przenoszone do kolejności określonej przez pakiet ... ale nie jestem pewien, ponieważ nie wiem, co to za pliki, co doprowadziło mnie zapytać . Chciałbym wiedzieć, czy korzystanie z IBundleOrderer działa dla Ciebie, ponieważ określenie zamówienia nie.
MikeSmithDev,
spójrz na odpowiedź @Softlion w [ten link] [1] [1]: stackoverflow.com/questions/11979718/…
Omid-RH
@section Scripts { @Scripts.Render("~/bundles/jqueryval") }wydaje się, że rozwiązał problem z ładowaniem moich skryptów
niedziałających

Odpowiedzi:

103

Domyślnie kolejność grupowania jest alfabetyczna dla nazw z symbolami wieloznacznymi (jak wskazano w komentarzach). Jednak porządkuje również na podstawie tego, co według niego jest twoje drzewo zależności, ijQuery skrypty wydają się być umieszczane na górze. Musisz stworzyć obiekt, który implementuje IBundleOrder:

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

Zapobiega to domyślnemu porządkowaniu. Teraz, aby go użyć:

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/

Aby uzyskać więcej informacji, odpowiedź na pytanie MikeSmithDev zapewnia dalszy wgląd w domyślną kolejność popularnych bibliotek skryptów:

Kolejność plików w pakiecie - jakie są znane biblioteki?

Mister Epic
źródło
Nie żeby dziurkować, ale „domyślnie kolejność grupowania jest alfabetyczna” jest prawdą, gdy używasz takich rzeczy, jak symbole wieloznaczne… kiedy określasz kolejność, tak jak on, powinna używać jego kolejności. Mogę tylko założyć, że bundler porusza się po znanych typach plików i ignoruje jego kolejność.
MikeSmithDev,
Wygląda na to, że bundler również zamawia przy użyciu logiki dotyczącej zależności. Uważa, że jquery.validate.globalize.jsjest to wymagane dla pozostałych dwóch. Z ref: „[Bundler] automatycznie umieści nawet znane pliki javascript frameworków jako pierwsze w pakiecie, takie jak skrypty jQuery lub Prototype, aby upewnić się, że zostaną uruchomione, zanim Twój własny kod wykorzystujący ich typy zostanie wykonany”
Mister Epic
3
Kolejność specyficzna to: 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
tutaj programowanie nie jest zabawne. dlaczego VS to komplikuje?
Jaider
5
Fakt, że to istnieje, wprawia mnie w zdumienie, jak głupie to jest. Naprawdę ... pakiet wie lepiej, jak uporządkować zależności, niż je wpisałem? Gulp.js (lub nawet Grunt) FTW!
John Culviner
30

W ostatniej wersji MVC 5 (27 października 2014 r.) Należy zamiast tego użyć tej klasy:

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

I utwórz pakiet jak inną odpowiedź:

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
źródło
Gdzie mogę znaleźć te informacje? Czy możesz podać link?
PussInBoots
Po prostu próbuję użyć metody bieżącej odpowiedzi na to pytanie, ale znalazłem mój selkf z błędem w ASP.NET MVC 5, więc sprawdzam interfejs IBundleOrderer i wprowadziłem zmiany
Sebastián Rojas
Nie ma własności zleceniodawcy. Używam MVC 5.2.x
Legends
1
Po prostu testuję to z MVC 5.2.3 i tehres jest własnością Zamawiającego.
Sebastián Rojas
29

Aby zmniejszyć kody podczas tworzenia paczek, sugeruję utworzenie metody rozszerzającej.

Wymagaj klas infrastruktury:

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;
    }
}

Teraz po prostu użyj tego w ten sposób:

Wszystko w jednym poleceniu 😎

bundles.Add(new ScriptBundle("~/bundles/jqueryval")
               .NonOrdering()
               .Include(
                    "~/Scripts/globalize/globalize.js",
                    "~/Scripts/globalize/cultures/globalize.culture.es-CL.js",
                    //...
                );
Baran
źródło
1
Niezły sposób myślenia!
Aruna,