11

Używanie najnowszej wersji MVC4 Nie mogę zminimalizować javascript, gdy zawiera zastrzeżone słowa jako nazwy kluczy!MVC4 Minifigacja zestawu nie działa z zastrzeżonymi słowami javascript

Zobacz błąd poniżej z poprawnym javascript, który powinien być minified.

Czy ktoś wie, jak rozwiązać ten problem, przepisując javascript do notacji [""]?

PS Kod, o którym mowa, ma kilka tysięcy linii, więc nie jest to opcja!

/* Minification failed. Returning unminified contents. 
(3,9-15): run-time warning JS1010: Expected identifier: delete 
(4,9-13): run-time warning JS1010: Expected identifier: case 
(5,9-11): run-time warning JS1010: Expected identifier: if 
(3,9-15): run-time error JS1137: 'delete' is a new reserved word and should not be used as an identifier: delete 
(4,9-13): run-time error JS1137: 'case' is a new reserved word and should not be used as an identifier: case 
(5,9-11): run-time error JS1137: 'if' is a new reserved word and should not be used as an identifier: if 
*/ 
var context = {}; 

context.delete = {}; 
context.case = {}; 
context.if = {}; 

Pytanie jest bez wychodzenia z innej opcji jak węzeł, kasety, Combres, servicestack itp

jaki sposób możemy uzyskać MVC4 grać w piłkę ze słowami zastrzeżonymi.

Trudno mi uwierzyć, że po 6 miesiącach i że nie ma na to poparcia!

+3

Właśnie wypróbowałem to moje własne i pierwsze myślenie. Hej, zadziałało, ponieważ nie było żadnego widocznego wyjątku. Ale zamiast tego gówno nie zostało zminimalizowane, a podstępny mały komentarz został wprowadzony w JS. To naprawdę brzydkie. – Daniel

+1

Nie testowałem, ale Builder wydaje się być przełączalny na pakiet. Nie możesz przypisać takiego, który zmienia wartości? Być może przy użyciu JsParser w WebGrease i przy użyciu Settings.AddRenamePair? – Daniel

+0

Hej James. Dobre pytanie, ale dlaczego pakietowanie wspierałoby słowa zastrzeżone, gdy standard ECMASscript odradza ich używanie? https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Reserved_Words – garfbradaz

Odpowiedz

8

Próbowałem tego i działa. Przepraszam, ale brzydki kod. Zastąpi twoich członków o nazwie delete i ich zastosowania.

public class CustomBundle : ScriptBundle 
{ 
    public CustomBundle(string virtualPath) : base(virtualPath) 
    { 
     this.Builder = new CustomBuilder(); 
    } 
    public CustomBundle(string virtualPath, string cdnPath) : base(virtualPath, cdnPath) {} 
} 

public class CustomBuilder : IBundleBuilder { 
    public string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<FileInfo> files) 
    { 
     var content = new StringBuilder(); 
     foreach (var fileInfo in files) 
     { 
      var parser = new Microsoft.Ajax.Utilities.JSParser(Read(fileInfo)); 
      parser.Settings.AddRenamePair("delete", "fooDelete"); 
      content.Append(parser.Parse(parser.Settings).ToCode()); 
      content.Append(";"); 
     } 

     return content.ToString(); 
    } 

    private string Read(FileInfo file) 
    { 
     using(var r = file.OpenText()) 
     { 
      return r.ReadToEnd(); 
     } 
    } 
} 
+0

To jest niesamowite Daniel, zdecydowanie będę miał z tym zabawę. – garfbradaz

+1

Niezbyt dużo miłości w kodzie, ale przełączy je, ale tylko wtedy, gdy minie. Blog o tym tutaj: http://daniel.wertheim.se/2012/11/16/customizing-the-minification-of-javascript- in-asp-net-mvc4-allow-reserved-words/ – Daniel

+0

Czy zgodziłbyś się, czy byłby bardziej wydajny, aby umieścić ten rodzaj logiki w jednym skrypcie MSBuild? – garfbradaz

2

Mam nadzieję, że nie jest za późno. Możesz zaimplementować własną transformację i zignorować te błędy.

var bundle = new ScriptBundle("~/bundles/xxxbundle", null, new JsMinifyIgnoreReservedWordError()). 
    Include("~/Scripts/xxx.js"); 

private class JsMinifyIgnoreReservedWordError : IBundleTransform 
{ 
    private const string JsContentType = "text/javascript"; 

    public void Process(BundleContext context, BundleResponse response) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     if (response == null) 
     { 
      throw new ArgumentNullException("response"); 
     } 
     if (!context.EnableInstrumentation) 
     { 
      Minifier minifier = new Minifier(); 

      string result = minifier.MinifyJavaScript(response.Content, new CodeSettings 
      { 
       EvalTreatment = EvalTreatment.MakeImmediateSafe, 
       PreserveImportantComments = false, 
         IgnoreErrorList = "JS1137" // ignore 'is a new reserved word and should not be used as an identifier' error 
        }); 

      if (minifier.ErrorList.Count > 0) 
      { 
       GenerateErrorResponse(response, minifier.ErrorList); 
      } 
      else 
      { 
       response.Content = result; 
      } 
     } 
     response.ContentType = JsContentType; 
    } 

    private static void GenerateErrorResponse(BundleResponse bundle, IEnumerable<object> errors) 
    { 
     StringBuilder stringBuilder = new StringBuilder(); 

     stringBuilder.Append("/* "); 
     stringBuilder.Append("Minification failed. Returning unminified contents.").AppendLine(); 

     foreach (object error in errors) 
     { 
      stringBuilder.Append(error).AppendLine(); 
     } 

     stringBuilder.Append(" */").AppendLine(); 
     stringBuilder.Append(bundle.Content); 

     bundle.Content = stringBuilder.ToString(); 
    } 
} 
+1

dzięki @bigbangbyproduct, że jestem w stanie to zrobić, ale muszę zmienić 'ScriptBundle' na' Bundle', ponieważ ma on poprawne parametry konstruktora. –

+1

również, aby dodać więcej numerów błędów do ignoreerrorlist, możesz użyć wartości oddzielonych przecinkami. –