Come posso specificare un object ScriptBundle esplicito?

Sto provando la funzione ScriptBundle di MVC4 System.Web.Optimization 1.0 .

Ho la seguente configurazione:

public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { // shared scripts Bundle canvasScripts = new ScriptBundle(BundlePaths.CanvasScripts) .Include("~/Scripts/modernizr-*") .Include("~/Scripts/json2.js") .Include("~/Scripts/columnizer.js") .Include("~/Scripts/jquery.ui.message.min.js") .Include("~/Scripts/Shared/achievements.js") .Include("~/Scripts/Shared/canvas.js"); bundles.Add(canvasScripts); } } 

e la seguente vista:

  

dove BundlePaths.CanvasScripts è "~/bundles/scripts/canvas" . Lo rende:

  

Fin qui tutto bene, tranne ~/Scripts/Shared/achievements.js è il primo script nel sorgente in bundle. Dipende da ogni script incluso prima di esso in ScriptBundle . Come posso garantire che rispetti l’ordine in cui aggiungo le istruzioni di inclusione al pacchetto?

Aggiornare

Si trattava di un’applicazione ASP.NET MVC 4 relativamente nuova, ma faceva riferimento al pacchetto di pre-release del framework di ottimizzazione. L’ho rimosso e aggiunto il pacchetto RTM da http://nuget.org/packages/Microsoft.AspNet.Web.Optimization . Con la versione RTM con debug = true in web.config, @Scripts.Render("~/bundles/scripts/canvas") esegue il rendering dei singoli tag di script nell’ordine corretto.

Con debug = false in web.config, lo script combinato ha per primo lo script achievements.js, ma poiché è una definizione di funzione (costruttore di oggetti) chiamata in seguito, viene eseguita senza errori. Forse il minificatore è abbastanza intelligente da capire le dipendenze?

Ho anche provato l’implementazione di IBundleOrderer che Darin Dimitrov ha suggerito con RTM con entrambe le opzioni di debug e si è comportato allo stesso modo.

Quindi la versione minificata non è nell’ordine che mi aspetto, ma funziona.

Non vedo questo comportamento sui bit RTM, stai utilizzando i bit 1.0.0 di Microsoft Web Optimization Framework 1.0: http://nuget.org/packages/Microsoft.AspNet.Web.Optimization ?

Ho usato una replica simile al tuo campione, basata su un nuovo sito Web di applicazioni Internet MVC4.

Ho aggiunto a BundleConfig.RegisterBundles:

  Bundle canvasScripts = new ScriptBundle("~/bundles/scripts/canvas") .Include("~/Scripts/modernizr-*") .Include("~/Scripts/Shared/achievements.js") .Include("~/Scripts/Shared/canvas.js"); bundles.Add(canvasScripts); 

E poi nella pagina indice predefinita, ho aggiunto:

  

E ho verificato che nel javascript minificato per il pacchetto, il contenuto di achievements.js era dopo modernizr …

È ansible scrivere un ordinatore di pacchetti personalizzato ( IBundleOrderer ) che garantirà che i pacchetti siano inclusi nell’ordine in cui li si registra:

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

e poi:

 public class BundleConfig { public static void RegisterBundles(BundleCollection bundles) { var bundle = new Bundle("~/bundles/scripts/canvas"); bundle.Orderer = new AsIsBundleOrderer(); bundle .Include("~/Scripts/modernizr-*") .Include("~/Scripts/json2.js") .Include("~/Scripts/columnizer.js") .Include("~/Scripts/jquery.ui.message.min.js") .Include("~/Scripts/Shared/achievements.js") .Include("~/Scripts/Shared/canvas.js"); bundles.Add(bundle); } } 

e secondo te

 @Scripts.Render("~/bundles/scripts/canvas") 

Grazie, Darin. Ho aggiunto un metodo di estensione.

 internal class AsIsBundleOrderer : IBundleOrderer { public virtual IEnumerable OrderFiles(BundleContext context, IEnumerable files) { return files; } } internal static class BundleExtensions { public static Bundle ForceOrdered(this Bundle sb) { sb.Orderer = new AsIsBundleOrderer(); return sb; } } 

uso

 bundles.Add(new ScriptBundle("~/bundles/jquery").Include( "~/Scripts/jquery-{version}.js", "~/Scripts/jquery-migrate-{version}.js", "~/Scripts/jquery.validate.js", "~/Scripts/jquery.validate.messages_fr.js", "~/Scripts/moon.jquery.validation-{version}.js", "~/Scripts/jquery-ui-{version}.js" ).ForceOrdered()); 

Aggiornato la risposta fornita da SoftLion per gestire le modifiche in MVC 5 (BundleFile vs FileInfo).

 internal class AsIsBundleOrderer : IBundleOrderer { public virtual IEnumerable OrderFiles(BundleContext context, IEnumerable files) { return files; } } internal static class BundleExtensions { public static Bundle ForceOrdered(this Bundle sb) { sb.Orderer = new AsIsBundleOrderer(); return sb; } } 

Uso:

  bundles.Add(new ScriptBundle("~/content/js/site") .Include("~/content/scripts/jquery-{version}.js") .Include("~/content/scripts/bootstrap-{version}.js") .Include("~/content/scripts/jquery.validate-{version}") .ForceOrdered()); 

Mi piace usare la syntax fluente ma funziona anche con una singola chiamata di metodo e tutti gli script passati come parametri.

Dovresti essere in grado di impostare l’ordine con l’aiuto di BundleCollection.FileSetOrderList. Date un’occhiata a questo post del blog: http://weblogs.asp.net/imranbaloch/archive/2012/09/30/hidden-options-of-asp-net-bundling-and-minification.aspx . Il codice nella tua istanza sarebbe qualcosa di simile:

 BundleFileSetOrdering bundleFileSetOrdering = new BundleFileSetOrdering("js"); bundleFileSetOrdering.Files.Add("~/Scripts/modernizr-*"); bundleFileSetOrdering.Files.Add("~/Scripts/json2.js"); bundleFileSetOrdering.Files.Add("~/Scripts/columnizer.js"); bundleFileSetOrdering.Files.Add("~/Scripts/jquery.ui.message.min.js"); bundleFileSetOrdering.Files.Add("~/Scripts/Shared/achievements.js"); bundleFileSetOrdering.Files.Add("~/Scripts/Shared/canvas.js"); bundles.FileSetOrderList.Add(bundleFileSetOrdering); 

Dovresti prendere in considerazione l’utilizzo di Cassette http://getcassette.net/ Supporta il rilevamento automatico delle dipendenze dello script in base ai riferimenti di script trovati all’interno di ciascun file.

Se si preferisce attenersi alla soluzione di MS Web Optimization ma come l’idea di organizzare script basati su riferimenti di script, si dovrebbe leggere il mio post sul blog su http://blogs.microsoft.co.il/oric/2013/12/27/building-single -page-application-fascio-orderer /

La risposta di @Darin Dimitrov funziona perfettamente per me, ma il mio progetto è scritto in VB, quindi ecco la sua risposta convertita in VB

 Public Class AsIsBundleOrderer Implements IBundleOrderer Public Function IBundleOrderer_OrderFiles(ByVal context As BundleContext, ByVal files As IEnumerable(Of FileInfo)) As IEnumerable(Of FileInfo) Implements IBundleOrderer.OrderFiles Return files End Function End Class 

Per usarlo:

 Dim scriptBundleMain = New ScriptBundle("~/Scripts/myBundle") scriptBundleMain.Orderer = New AsIsBundleOrderer() scriptBundleMain.Include( "~/Scripts/file1.js", "~/Scripts/file2.js" ) bundles.Add(scriptBundleMain)