问题 MVC4捆绑缩小不适用于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 = {};

问题是没有选择节点,盒式磁带,梳理,服务栈等其他选项

我们如何让MVC4用保留字来打球。

我发现很难相信在6个月之后加上没有支持!


8306
2017-11-16 09:34


起源

只是尝试了我自己,并首先想到。嘿它有效,因为没有显示明显的异常。但相反,狗屎没有缩小,并且在JS中输入了一个偷偷摸摸的小评论。那太难看了。 - Daniel
没有经过测试,但Builder似乎可以根据Bundle进行切换。你不能指定一个切换值吗?也许在WebGrease中使用JsParser并使用Settings.AddRenamePair? - Daniel
嘿詹姆斯。一个很好的问题,但是当ECMASscript标准建议不使用时,为什么Bundling会支持保留字? developer.mozilla.org/en-US/docs/JavaScript/Reference/... - garfbradaz
如果你发现它周围虽然我有兴趣知道。 - garfbradaz
实际上我想知道是否可以添加一些内容(就像我们用于LESS等)可能会自动将保留字替换为“”符号.... mmmmmnnn现在这就是构建一些有趣的东西。 - garfbradaz


答案:


刚试过这个就可以了。对不起,但丑陋的代码。它将取代您命名的成员 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();
        }
    }
}

8
2017-11-16 14:49



这是真棒丹尼尔,我肯定会玩这个。 - garfbradaz
在代码中没有多少爱,但它会切换它们,但只有在minifiying时。在此博文: daniel.wertheim.se/2012/11/16/... - Daniel
您是否同意在某些MSBuild脚本中使用这种逻辑会更有效率? - garfbradaz
我想我认为优化框架可以很好地工作。前一段时间使用,在通过调用某些NodeJS脚本构建代码时触发,该脚本可以在我们的构建过程中单独使用。我觉得这种解决方案与开发人员一起工作要麻烦得多。 - Daniel
谢谢Daniel。在我玩完Windows 8 / C#XAML之后,我将会看一下你的代码,并对它有一个很好的发挥。我喜欢这样的问题,阻止你工作和思考一个特定的问题。 - garfbradaz


希望现在还为时不晚。您可以实现自己的缩小变换并忽略这些错误。

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();
    }
}

2
2017-11-18 17:12



谢谢@bigbangbyproduct我能够做到这一点,但我必须改变 ScriptBundle 至 Bundle 因为它具有正确的构造函数参数。 - Aizzat Suhardi
另外,要向ignoreerrorlist添加更多错误号,可以使用逗号分隔值。 - Aizzat Suhardi