Микшер MVC4 Bundle не работает с зарезервированными словами javascript
Используя последнюю версию MVC4, я не могу минимизировать javascript, когда он содержит зарезервированные слова в качестве имен ключей!
См. приведенную ниже ошибку с допустимым javascript, который должен был быть уменьшен.
Кто-нибудь знает, как исправить это, не переписывая javascript для использования [""] нотации?
PS Этот код имеет длину несколько тысяч строк, поэтому это не вариант!
/* 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 = {};
Вопрос не идет с другим вариантом, например node, кассетой, combres, servicestack и т.д.
Как мы получаем MVC4 для игры в мяч с зарезервированными словами.
Мне трудно поверить, что через 6 месяцев плюс, что нет поддержки для этого!
Ответы
Ответ 1
Просто попробовал это, и он работает. Извините, но уродливый код. Он заменит ваших членов с именем delete
и их использования.
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();
}
}
}
Ответ 2
Надеюсь, что не поздно. Вы можете реализовать собственное преобразование минимизации и проигнорировать эти ошибки.
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();
}
}