2014-04-11 16 views
12

Ich versuche, viele .js-Dateien unter Verwendung von Microsoft Web Optimization framework in eine einzige Datei zu fassen. Alles funktioniert, aber innerhalb dieser Dateien habe ich mehrere, die bereits & egglified sind und es nicht notwendig, sie erneut zu verarbeiten.Verändern Sie bestimmte Dateien nicht, wenn Sie Microsoft Web Optimization Framework verwenden.

Zum Beispiel habe ich recaptcha_ajax.js Datei und verursacht Fehler folgenden, wenn es angehängt ist:

/* Minification failed. Returning unminified contents. 
(715,29-36): run-time error JS1019: Can't have 'break' outside of loop: break t 
(714,293-300): run-time error JS1019: Can't have 'break' outside of loop: break t 
(678,210-217): run-time error JS1019: Can't have 'break' outside of loop: break t 
(671,1367-1374): run-time error JS1019: Can't have 'break' outside of loop: break t 
(665,280-287): run-time error JS1019: Can't have 'break' outside of loop: break t 
*/ 

Ich habe versucht, recaptcha_ajax.js aus Bündel zu nehmen zu nehmen und es direkt verweisen, dann aber andere Fehler popup - also brauche ich diese Datei innerhalb des Bundles an einer bestimmten Position.

Ich muss nur sagen können - nicht verkleinern & uglify recaptcha_ajax.js - fügen Sie es einfach zum Bundle hinzu.

Gibt es eine Möglichkeit, dies zu tun? Hier ist, wie ich es sehe:

var b = new ScriptBundle("~/bundles/myjsbundle"); 

b.IncludeDirectory("~/ScriptsMine/", "*.js", true); 

// some command like: 
// b.DoNotMinifyOrUglify("~/ScriptsMine/recaptcha_ajax.js"); 

bundles.Add(b); 
+0

Bündeln Sie im Scriptmanager? – fnostro

Antwort

23

Bundles verwandeln jede Datei durch eine Sammlung von IItemTransform und verketten belegt wird. Dann transformieren Sie das Ergebnis mit einer Sammlung von IBundleTransform.

Das Standard-Skriptbündel minifies das komplette Gebinde Inhalt von JsMinify mit (die IBundleTransform implementiert).

Um zu verhindern, dass eine Datei verkleinert wird, müssen Sie Ihre eigene IBundleBuilder erstellen, die die Bundle-Datei nach Datei unter Verwendung einer IItemTransform minimiert.

public class CustomScriptBundle : Bundle 
{ 
    public CustomScriptBundle(string virtualPath) 
     : this(virtualPath, null) 
    { 
    } 

    public CustomScriptBundle(string virtualPath, string cdnPath) 
     : base(virtualPath, cdnPath, null) 
    { 
     this.ConcatenationToken = ";" + Environment.NewLine; 
     this.Builder = new CustomBundleBuilder(); 
    } 
} 


public class CustomBundleBuilder : IBundleBuilder 
{ 
    internal static string ConvertToAppRelativePath(string appPath, string fullName) 
    { 
     return (string.IsNullOrEmpty(appPath) || !fullName.StartsWith(appPath, StringComparison.OrdinalIgnoreCase) ? fullName : fullName.Replace(appPath, "~/")).Replace('\\', '/'); 
    } 

    public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files) 
    { 
     if (files == null) 
      return string.Empty; 
     if (context == null) 
      throw new ArgumentNullException("context"); 
     if (bundle == null) 
      throw new ArgumentNullException("bundle"); 

     StringBuilder stringBuilder = new StringBuilder(); 
     foreach (BundleFile bundleFile in files) 
     { 
      bundleFile.Transforms.Add(new CustomJsMinify()); 
      stringBuilder.Append(bundleFile.ApplyTransforms()); 
      stringBuilder.Append(bundle.ConcatenationToken); 
     } 

     return stringBuilder.ToString(); 
    } 
} 

public class CustomJsMinify : IItemTransform 
{ 
    public string Process(string includedVirtualPath, string input) 
    { 
     if (includedVirtualPath.EndsWith("min.js", StringComparison.OrdinalIgnoreCase)) 
     { 
      return input; 
     } 

     Minifier minifier = new Minifier(); 
     var codeSettings = new CodeSettings(); 
     codeSettings.EvalTreatment = EvalTreatment.MakeImmediateSafe; 
     codeSettings.PreserveImportantComments = false; 

     string str = minifier.MinifyJavaScript(input, codeSettings); 

     if (minifier.ErrorList.Count > 0) 
      return "/* " + string.Concat(minifier.Errors) + " */"; 

     return str; 
    } 
} 

dann die CustomScriptBundleScriptBundle

public static void RegisterBundles(BundleCollection bundles) 
{ 
    bundles.Add(new CustomScriptBundle("~/bundles/Sample").Include(
       "~/Scripts/a.js", 
       "~/Scripts/b.js", 
       "~/Scripts/c.js")); 
} 

Wenn Sie statt minifying es statt einer min.js Datei bereitstellen verwenden wird es verwendet werden.

+0

Dies geht nicht mit dem Fall, wenn das Bundle enthält die min-und nicht-min-Versionen einer Bibliothek, richtig? Es sollte in der Konfigurationsdatei verwenden, um zu entscheiden, welche verwendet werden soll. Diese Verarbeitung könnte vor der foreach in der BuildBundleContent-Methode hinzugefügt werden. –

+0

Dieser Code wurde nicht vollständig getestet, daher können Sie einige Änderungen vornehmen, damit es wie gewünscht funktioniert – meziantou

2

Das Optimierungsframework berücksichtigt Dateinamen.

Versuchen Sie, Ihre * .js-Datei in recaptcha_ajax.min.js umzubenennen. Wenn ich richtig bin, sollte der Prozess hugh/minify übersprungen werden.

Daten Referenz: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification (scrollen ein wenig nach unten, dieses Zitat zu finden :)

Der obige Code erstellt ein neues JavaScript Bündel ~/Bündel/jquery genannt, die alle entsprechenden enthält (dh debug oder verkleinerte aber nicht .vsdoc) Dateien im Ordner Scripts, die der Platzhalterzeichenfolge "~/Scripts/jquery- {version} .js" entsprechen. Für ASP.NET MVC 4, bedeutet dies, dass bei einer Debugkonfiguration die Datei jquery-1.7.1.js dem Paket hinzugefügt wird. In einer Release-Konfiguration wird jquery-1.7.1.min.js hinzugefügt. Die Bündelung Rahmen folgt mehrere gemeinsame Konventionen wie:

  • Auswahl von „· min“ Datei für die Freigabe, wenn „FileX.min.js“ und „FileX.js“ existieren.
  • Auswählen der Nicht-Version ".min" für das Debuggen.
  • Ignorieren von "-vsdoc" -Dateien (z. B. jquery-1.7.1-vsdoc.js), die nur von IntelliSense verwendet werden.
+0

Es wäre toll, wenn es so funktioniert. Aber es scheint, dass es nicht - Ich habe separate hello.js und hello.min.js zum Testen erstellt und minimiert es unabhängig von. Min. im Namen. Vielleicht fehlt mir etwas Einstellung? – kape123

+0

Haben Sie versucht, es im Freigabemodus auszuführen? Es sollte so funktionieren: s – Yoeri

+3

Ich denke, es ist nur schlechtes Engineering - Web-Optimierung-Framework hat so viele Schalter, dass es scheint, direkt zu ändern, Bündel-Prozess ist die einzige Möglichkeit, es zu kontrollieren. Beispiel: Unabhängig vom Debug/Release-Modus hat BundleTable.EnableOptimizations Vorrang (was eine gute Sache ist). Wenn BundleTable.EnableOptimizations = false ist, wird die Datei script.js ausgewählt. Für wahr, script.min.js. ABER - BEIDE Dateien werden ungeachtet des Dateinamens minimiert. Ich würde es lieben, wenn sie Open-Source-Code, so dass wir ihnen ein wenig mit Design-Entscheidungen helfen könnten (d. H. Nicht für .min.js im Dateinamen minimieren). – kape123

1

wenn Sie bündeln Js Dateien im Script werden Sie feststellen, dass Skripte im <form> geladen wird, nicht die <head> so dass es aus dem Bündel zieht vor den anderen die Datei geladen werden kann, was nicht gut ist, wenn es abhängig ist andere Dinge im Bündel

Hier ist ein Beispiel für eine Bibliothek, die dem Bundle in einer bestimmten Reihenfolge hinzugefügt werden muss.
Dies wird zu App_Start/BundleConfig.vb

'############################################################ 
' This is a ScriptManager Resource Definition 
' for use in a ScriptManager mapping 
'############################################################ 
    Dim ResourceDef as ScriptResourceDefinition = New ScriptResourceDefinition() 
    Dim ResourceName as String = "ColorBox" 

    'add the Resource Definition details 
    ResourceDef.Path = "~/Scripts/colorbox/jquery.colorbox-min.js" 
    ResourceDef.DebugPath = "~/Scripts/colorbox/jquery.colorbox.js" 

    ScriptManager.ScriptResourceMapping.AddDefinition(ResourceName, ResourceDef) 
'############################################################ 

Beachten Sie die Verwendung von und ResourceDef.DebugPath. Welche Datei enthalten wird von Ihnen abhängen wird eine Debug machen oder Release veröffentlichen

  • Debug: keine "Verhäßlichung"
  • Release: Total "Verhäßlichung"

Das ist mein Script Bündel, beachten Sie das Platzierung der ColorBox, Position bedeutet viel:

<asp:ScriptManager runat="server" > 
    <Scripts> 
     <asp:ScriptReference Name="jquery" /> 
     <asp:ScriptReference Name="jquery.ui.combined" /> 
     <asp:ScriptReference Name="ColorBox" />   
     <asp:ScriptReference Name="Infragistics" /> 
     <asp:ScriptReference Name="MsAjaxBundle" /> 
     <asp:ScriptReference Name="WebForms.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebForms.js" /> 
     <asp:ScriptReference Name="WebUIValidation.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebUIValidation.js" /> 
     <asp:ScriptReference Name="MenuStandards.js" Assembly="System.Web" Path="~/Scripts/WebForms/MenuStandards.js" /> 
     <asp:ScriptReference Name="GridView.js" Assembly="System.Web" Path="~/Scripts/WebForms/GridView.js" /> 
     <asp:ScriptReference Name="DetailsView.js" Assembly="System.Web" Path="~/Scripts/WebForms/DetailsView.js" /> 
     <asp:ScriptReference Name="TreeView.js" Assembly="System.Web" Path="~/Scripts/WebForms/TreeView.js" /> 
     <asp:ScriptReference Name="WebParts.js" Assembly="System.Web" Path="~/Scripts/WebForms/WebParts.js" /> 
     <asp:ScriptReference Name="Focus.js" Assembly="System.Web" Path="~/Scripts/WebForms/Focus.js" /> 
     <asp:ScriptReference Name="WebFormsBundle" /> 
    </Scripts> 
</asp:ScriptManager>