11

Nehmen wir an, unsere App ist offline, d. H. Wir können keine CDNs von Drittanbietern verwenden, daher erstellen wir unsere eigenen. Ich möchte alle Hersteller-Skripts in einer separaten (übergeordneten) Web-App hosten und sie dann in die Bundles in mehreren anderen MVC-Apps einbinden.Erstellen eines Skriptpakets aus mehreren CDN-Verzeichnissen

z.B.

  • http://localhost/parentWeb/Scripts/jquery.js
  • http://localhost/parentWeb/Scripts/jquery-ui.js
  • http://localhost/parentWeb/Scripts/globalize.js

Ich möchte in der ASP.NET MVC App Webseite in sich aufzunehmen: http://localhost/parentWeb/childWeb

also etwas tun:

bundles.UseCdn = true; 
bundles.Add(
    new ScriptBundle(
     "~/bundles/VendorScripts", 
     "http://localhost/parentWeb/Scripts/jquery.js", 
     "http://localhost/parentWeb/Scripts/jquery-ui.js", 
     "http://localhost/parentWeb/Scripts/globalize.js")); 

... was natürlich zur Zeit nicht möglich ist. Gibt es eine gute Problemumgehung?

Antwort

6

Ich habe eine Lösung gefunden, die nichts mit CDN zu tun hat. Grundsätzlich gewährt die childWeb in der parentWeb ‚s Unterverzeichnis gehostet wird, wird die folgende Bündelkonfiguration in den childWeb Anwendungen nimmt die Datei aus dem parentWeb und bündelt sie wie gewohnt:

bundles.Add(
    new ScriptBundle(
     "~/bundles/VendorScripts").Include(
     "~/../Scripts/jquery.js", 
     "~/../Scripts/Scripts/jquery-ui.js", 
     "~/../Scripts/globalize.js")); 

das wichtige Bit Wesen: ~/../, der nimmt Sie eine Ebene von der Root-Position.

+0

so mit Ihrer Lösung, wo ist Store CDN-Pfad in diesem Code habe ich das gleiche Problem, ich brauche auch mehrere CSS im Bundle mit CDN laden so können Sie bitte lassen Sie mich wissen, wie kann das tun? – coderwill

13

Sie können keine externen Ressourcen bündeln. Wenn Sie darüber nachdenken, macht es Sinn, warum Sie nicht können. Es würde erfordern, dass der Bündler die Ressource tatsächlich herunterlädt und sie in dem Dateisystem speichert, bevor sie damit arbeiten könnte, und natürlich alles asynchron mit irgendeiner Art von Fallback, wenn die externe Ressource nicht erreicht werden könnte. Und dann müsste es dies auf jede Seite laden tun, weil es nicht nach lastmod (und daher, wissen, ob es tatsächlich neu oder nicht neu zu bonden), ohne die Ressource zuerst abrufen muss.

Wenn Sie eine CDN-Ressource verwenden, druckt der Bundler lediglich die URL direkt auf die Seite; es macht keine Änderungen. Selbst dann können Sie nur ein "Bündel" nur dieser einen URL erstellen, weil 1) es nicht sinnvoll wäre, mehrere CDN-Ressourcen zu bündeln, da dies den Zweck eines CDNs zunichte machen würde und 2) das Paket nur in diesem existiert Szenario, um einen Fallback bereitzustellen, wenn die CDN-Ressource nicht verfügbar ist. Sonst würden Sie genauso gut bedient werden, indem Sie es einfach auf die Seite codieren und sich keine Gedanken darüber machen, ein Bundle überhaupt einzurichten.

+1

Während Sie externe Ressourcen nicht bündeln können (Ihre Punkte sind sehr korrekt) hat ScriptBundle tatsächlich Unterstützung für CDNs. Dieser Blogpost erklärt alles sehr gut http://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx –

+1

@BryanRayner: Nicht sicher, was der Konflikt ist. Ich habe nie gesagt, dass Bündelung keine CDN-Unterstützung hat. Ganz im Gegenteil, wie gesagt, CDNs mit Script-Bundles zu verwenden. Wie ich jedoch in meiner Antwort oben sage, tut der Bundler eigentlich nichts mit der CDN-Ressource. Es löscht nur ein statisches Skript-Tag auf der Seite in der CDN-Datei. Es wird nicht mit anderen Skripten oder CSS-Dateien minimiert/kombiniert. –

+0

Re-Lesen Sie Ihre Frage, ich muss zustimmen - Sie haben nie gesagt, Bündelung hat keine CDN-Unterstützung. Als ich Ihre Antwort zu Anfang gelesen habe, "Sie können keine externen Ressourcen bündeln" schien es, dass ScriptBundles nicht verwendet werden könnte, um externe Ressourcen für den Client bereitzustellen. –

1

Um ScriptBundles mit CDN-Ressourcen zu verwenden, müssen Sie den überladenen Konstruktor verwenden. Leider müssen Sie mehrere ScriptBundle s pro Datei angeben.

Hier ist eine große Blog-Post, Dinge zu erklären: http://www.hanselman.com/blog/CDNsFailButYourScriptsDontHaveToFallbackFromCDNToLocalJQuery.aspx

Und hier ist ein Code-Schnipsel:

bundles.UseCdn = true; 
var bundle = new ScriptBundle("~/bundles/bundleNameHere", "//cdn.host.path/to/file"); 
// Path to the version of the file on your server (in case the CDN fails) 
bundle.Include("~/../Scripts/path/to/file"); 
// JS expression to run, to test if CDN delivered the file or not 
bundle.CdnFallbackExpression = "window.ValueYouExpectToBeTruthy"; 

bundles.Add(bundle); 
6

Ich weiß, dies ist ein altes Thema, aber ich kam hier für einen tatsächlichen Weg suchen, zu bündeln CDN-Ressourcen. Von @Chris Pratt 's Antwort verstand ich, dass es nicht möglich war.

Wenn Sie sich fragen, ich arbeite an der Optimierung eines vorhandenen Projekts nach Google's Web Performance Best Practises, die eine niedrige Punktzahl gibt, wenn mehrere Skript-Tags und eine höhere, wenn alle Skripte in einem einzigen Skript-Verweis gebündelt sind.

Ich brauchte einen Weg, um alle CDN-Skript-Ressourcen sowie lokale Ressourcen in der Reihenfolge zu bündeln. Ich arbeitete an dieser github repo, die mein Problem löste.

Damit erstellen Sie ein Bundle mit einer Liste von Bundles, die jeweils einen Verweis auf die cdn-Ressource, eine lokale Ressource zum Speichern und einen Booleschen Wert enthalten, der angibt, ob das Bundle minimiert werden soll oder nicht.

List<Bundle> jsBundles = new List<Bundle>(); 
jsBundles.Add(new Bundle("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js", @"~/jquery.min.js", Bundle.BundleType.JavaScript, false)); 
jsBundles.Add(new Bundle("https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js", @"~/jquery-ui.min.js", Bundle.BundleType.JavaScript, false)); 
jsBundles.Add(new Bundle(@"~/my-local-script.js", Bundle.BundleType.JavaScript, true)); 

auf der Seite zu platzieren, die Sie verwenden

@jsBundles.Load(); 

Dadurch werden alle Pakete in der Liste bearbeiten, Inhalte für Pakete herunterzuladen, die in den letzten 24 Stunden heruntergeladen haben (Es aktualisiert alle nicht 24 Stunden oder wenn die Webanwendung neu gestartet wird). Der gesamte heruntergeladene Inhalt wird in lokalen Dateien gespeichert (wo angegeben).

Der gesamte Inhalt wird in das Endergebnis kombiniert, das in einem Skript-Tag (oder Link-Tag für CSS) in die Seite gespoolt wird.

Die Load-Funktion akzeptiert auch eine lokale Datei-URL für den endgültigen script/css-Inhalt. Wenn angegeben, wird stattdessen ein Tag mit einem src für den relativen Pfad für diese lokale Datei angegeben. Z.B.

@jsBundles.Load("~/js/all-my-scripts.js"); 

Die obige Aussage wird wieder so etwas wie:

<script src="~/js/all-my-scripts.js"></script> 

Ein Asynchron-Attribut in den Skript-Tag hinzugefügt werden kann, wenn der zweite Parameter der Load-Funktion vorgesehen ist.

Es funktioniert auch auf css cdn Ressourcen zu. Z.B.

Dies ist für diejenigen, die wie ich, kam hier auf der Suche nach einer Möglichkeit, CDN Ressourcen bündeln.

+0

Clevere Lösung, aber ist damit der Einsatz eines CDN nicht zu vereiteln?Webclients müssen die vollständigen gebündelten CDN-Skripts von Ihrem Server herunterladen, da sie diese nicht in ihren Caches haben. Bei echten CDN-Skriptverknüpfungen besteht die große Wahrscheinlichkeit, dass Ihr Webclient die Skriptdatei bereits zwischengespeichert hat, da viele andere Websites auf dieselbe CDN-URL verweisen. –