【问题标题】:Build events and versioning .js and .css files构建事件和版本控制 .js 和 .css 文件
【发布时间】:2009-10-02 17:06:47
【问题描述】:

我设置了一个 MSBuild 脚本来缩小和合并我的 javascript 和 css 文件。我现在需要的是一种对它们进行版本控制的方法。你们目前是如何处理这个问题的。对文件进行增量版本化并使用新文件名更新 <script/> 标记的最佳方法是什么?

【问题讨论】:

    标签: msbuild versioning


    【解决方案1】:

    我本来打算建议使用资源表达式来包含来自AppSettings的版本标签,但经过测试发现它只有在它是服务器控件属性的整个值时才有效。

    AppSettings 值可以由每个版本的构建脚本更新;可以是你喜欢的任何格式:

    <appSettings>
     <add key="versionTag" value="27" />
    </appSettings>
    

    作品:

    <asp:Label runat="server" Text="<%$ AppSettings: versionTag %>" />
    

    不起作用:

    <link runat="server" rel="Stylesheet" type="text/css"
          href='/css/site.css?v=<%$ AppSettings: versionTag %>' />
    

    所以我的实际建议是创建自己的控件来读取版本标签并将其包含在其输出中。这是我的 CSS 控件在页面上的外观(注意:服务器控件必须位于服务器端表单内,即使它可能呈现在 head 元素内):

    ...
    <form id="form1" runat="server">
     <my:Stylesheet runat="server" Url="~/css/site.css" />
    </form>
    ...
    

    我的样式表控件的代码:

    namespace MyNamespace
    {
        using System;
        using System.ComponentModel;
        using System.Configuration;
        using System.Security.Permissions;
        using System.Web;
        using System.Web.UI;
        using System.Web.UI.HtmlControls;
        using System.Web.UI.WebControls;
    
        /// <summary>
        /// Outputs a CSS stylesheet link that supports versionable caching via a
        /// build-specific query parameter.
        /// </summary>
        [
            AspNetHostingPermission(SecurityAction.InheritanceDemand,
                    Level = AspNetHostingPermissionLevel.Minimal),
            AspNetHostingPermission(SecurityAction.LinkDemand,
                    Level = AspNetHostingPermissionLevel.Minimal),
            DefaultProperty("Href"),
            ToolboxData(@"<{0}:Stylesheet runat=""server"" />")
        ]
        public class Stylesheet : WebControl
        {
            private static string versionTag = Stylesheet.GetVersionTag();
    
            /// <summary>
            /// Gets or sets the stylesheet URL.
            /// </summary>
            public string Href
            {
                get
                {
                    return this.ViewState["Href"] as string;
                }
    
                set
                {
                    this.ViewState["Href"] = value;
                }
            }
    
            /// <summary>
            /// Raises the PreRender event.
            /// </summary>
            /// <param name="e">Contains the event data.</param>
            protected override void OnPreRender(EventArgs e)
            {
                base.OnPreRender(e);
    
                HtmlLink link = new HtmlLink();
                link.Href = String.Format(
                        "{0}?v={1}",
                        this.Page.ResolveUrl(this.Href),
                        HttpUtility.UrlEncode(Stylesheet.versionTag));
    
                if (!Stylesheet.HeadContainsLinkHref(this.Page, link.Href))
                {
                    link.Attributes["type"] = "text/css";
                    link.Attributes["rel"] = "Stylesheet";
                    this.Page.Header.Controls.Add(link);
                }
            }
    
            /// <summary>
            /// Generates content to be rendered on the client.
            /// </summary>
            /// <param name="writer">Receives the server control content.</param>
            protected override void Render(HtmlTextWriter writer)
            {
                // Do nothing.
            }
    
            /// <summary>
            /// Retrieves the script version tag for this build.
            /// </summary>
            /// <returns>Returns the script version tag.</returns>
            private static string GetVersionTag()
            {
                string tag = ConfigurationManager.AppSettings["versionTag"];
                if (String.IsNullOrEmpty(tag))
                {
                    tag = "1";
                }
    
                return tag;
            }
    
            /// <summary>
            /// Determines if the page's <c>head</c> contains a <c>link</c> tag
            /// with a matching <c>href</c> attribute value.
            /// </summary>
            /// <param name="thePage">The Page to be tested.</param>
            /// <param name="href">The <c>href</c> URL to be matched.</param>
            /// <returns>Returns true if a matching link is already part of the
            /// page <c>head</c> or false otherwise.</returns>
            public static bool HeadContainsLinkHref(Page thePage, string href)
            {
                if (thePage == null)
                {
                    throw new ArgumentNullException("thePage");
                }
    
                foreach (Control control in thePage.Header.Controls)
                {
                    if ((control is HtmlLink) &&
                        (control as HtmlLink).Href == href)
                    {
                        return true;
                    }
                }
    
                return false;
            }
        }
    }
    

    HTH。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 2011-10-11
      • 2015-09-09
      • 1970-01-01
      相关资源
      最近更新 更多