如何保留MVC 4样式捆绑中重要的注释?

时间:2014-03-10 18:54:59

标签: asp.net asp.net-mvc-4 bundling-and-minification

我找到了这个链接:

http://giddyrobot.com/preserving-important-comments-in-mvc-4-bundles/

它展示了如何为JavaScript做同样的事情,我已经用它来尝试StyleBundles,但我不确定它是否在后端正确处理。

源代码是否可用?如果不是,有人知道这似乎是对的吗?我想要保留的是以/*!开头的注释,以便开源项目的许可证(例如normalize)可以正确地包含在生产中。

这是我到目前为止所做的:

public static void RegisterBundles(BundleCollection bundles)
{
    // Allows us to keep /*! comments for licensing purposes
    var cssBundleSettings = new CssSettings
    {
        CommentMode = CssComment.Important
    };
}

public class ConfigurableStyleBundle : Bundle
{
    public ConfigurableStyleBundle(string virtualPath, CssSettings cssSettings) :
        this(virtualPath, cssSettings, null) { }

    public ConfigurableStyleBundle(string virtualPath, CssSettings cssSettings, string cdnPath) :
        base(virtualPath, cdnPath, new[] { new ConfigurableCSSTransform(cssSettings) })
    {
        // commented out from js concatenation token not sure if this one should have one
        //base.ConcatenationToken = ";";
    }
}

[ExcludeFromCodeCoverage]
public class ConfigurableCSSTransform : IBundleTransform
{

    private readonly CssSettings _cssSettings;

    public ConfigurableCSSTransform(CssSettings cssSettings)
    {
        _cssSettings = cssSettings;
    }

    public void Process(BundleContext context, BundleResponse response)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        if (response == null)
        {
            throw new ArgumentNullException("response");
        }
        if (!context.EnableInstrumentation)
        {
            var minifier = new Minifier();
            var content = minifier.MinifyStyleSheet(response.Content, _cssSettings);
            if (minifier.ErrorList.Count > 0)
            {
                GenerateErrorResponse(response, minifier.ErrorList);
            }
            else
            {
                response.Content = content;
            }
        }
        response.ContentType = "text/css";
    }

    internal static void GenerateErrorResponse(BundleResponse bundle, IEnumerable<object> errors)
    {
        var content = new StringBuilder();
        content.Append("/* ");
        content.Append("CSS MinifyError").Append("\r\n");
        foreach (object current in errors)
        {
            content.Append(current.ToString()).Append("\r\n");
        }
        content.Append(" */\r\n");
        content.Append(bundle.Content);
        bundle.Content = content.ToString();
    }
}

所有这些都包含在public class BundleConfig中,并从Global.asax调用。

我只是想知道CssComment.Important是否会产生负面影响并删除太多,如果这似乎正在做我想要的事情?当我测试它时,所有东西看起来都是正确的样式,但是看到它并没有什么坏处,因为这对许多使用开源库的ASP.NET开发者来说可能是有用的。

1 个答案:

答案 0 :(得分:7)

我不认为你做错了什么。虽然我会使用IBundleBuilder接口来接近它,因为这也会使切换用户代理的窥探者不再定期发表评论,如How to prevent User-Agent: Eureka/1 to return source code中所述。我展示了如何针对此in this related blog post进行测试的一些步骤。

public class ConfigurableStyleBuilder : IBundleBuilder
{
    public virtual string BuildBundleContent(Bundle bundle, BundleContext context, IEnumerable<BundleFile> files)
    {
        var content = new StringBuilder();

        foreach (var file in files)
        {
            FileInfo f = new FileInfo(HttpContext.Current.Server.MapPath(file.VirtualFile.VirtualPath));
            CssSettings settings = new CssSettings();
            settings.CommentMode = Microsoft.Ajax.Utilities.CssComment.Important;
            var minifier = new Microsoft.Ajax.Utilities.Minifier();
            string readFile = Read(f);
            string res = minifier.MinifyStyleSheet(readFile, settings);
            if (minifier.ErrorList.Count > 0)
            {
                res = PrependErrors(readFile, minifier.ErrorList);
                content.Insert(0, res);
            }
            else
            {
                content.Append(res);
            }

        }

        return content.ToString();
    }

    private string PrependErrors(string file, ICollection<ContextError> errors )
    {
        var content = new StringBuilder();
        content.Append("/* ");
        content.Append("CSS MinifyError").Append("\r\n");
        foreach (object current in errors)
        {
            content.Append(current.ToString()).Append("\r\n");
        }
        content.Append("Minify Error */\r\n");
        content.Append(file);
        return content.ToString();
    }

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

public class BundleConfig
{
    public static void RegisterBundles(BundleCollection bundles)
    {          
        var cssBundle = new ConfigurableStyleBundle("~/Content/css");
        cssBundle.Include("~/Content/stylesheet1.css");
        cssBundle.Include("~/Content/stylesheet2.css");
        bundles.Add(cssBundle);

        //etc      
    }
}

我为此制作了一个NuGet包(包括脚本版本) - https://www.nuget.org/packages/LicensedBundler/