TFS Build 2010 - 在部署之前缩小JS / CSS

时间:2011-09-20 15:24:08

标签: visual-studio-2010 tfs tfs2010 team-build microsoft-web-deploy

我已经掌握了Ajax minifier,以便将一些JS和CSS文件缩小为构建/打包/部署过程的一部分。它是一个很棒的工具,完全符合我们的需要。但是,将其集成到我们的构建/部署过程中非常困难。

理想情况下,当我们执行一个TFS 2010版本(即本地(Ctrl + Shift + B jobbie))构建时,我们希望运行此工具 开发机器)。此外,我们希望在这种情况下用缩小的文件替换我们当前的“非缩小”文件(即在相同的文件名下),而不是加载一些名为“.min.js”等的附加文件。

经过大量阅读后,我认为关键是工作流程中的自定义构建任务 - 但我不知道如何处理这个问题 - 特别是因为我希望缩小直接下拉的文件从TFS中的发布分支(即不在某人的本地工作空间中)作为TFS 2010构建的一部分。

这是我发现的最接近的讨论:Microsoft Ajax Minifier - TFS 2010 Workflow - AjaxMin in the TFS Build

我相信我需要在构建工作流程中使用自定义代码活动,但不知道如何创建一个来解决此问题。任何人都可以对在部署之前允许缩小的过程有所了解吗?

3 个答案:

答案 0 :(得分:6)

好的 - 感谢这些答案和大量的研究......我来到了以下解决方案:)

从自定义代码活动开始,我尝试从C#代码运行minifier,然后将活动作为工作流的一部分调用。这不起作用,因为.dll版本的minifier暴露了几种压缩.js和.css文件的方法,然后让你打开某种类型的StreamWriter并用从中返回的压缩字符串重写该文件方法(如果您想覆盖现有文件)。非常密集地打开和关闭文件,所以我对该解决方案并不十分满意。使用进程类运行带有-clobber选项的.exe(用于覆盖文件)也不理想并产生一些奇怪的结果(没有正确地缩小文件并在每个文件的头部写一些垃圾)。

所以,你问,我解决的解决方案是编写一个PowerShell脚本(我从here开始 - 我稍后修改了一个命令行参数 - 这将是你的项目的根文件夹。脚本递归地遍历每个文件(和每个子目录的文件)并缩小里面的.css和.js。非常整洁。骨头看起来像这样:

$ScriptDirectory = $args[0]
Write-Host "Validating directory parameter: $ScriptDirectory"
Write-Host ""

if ((Test-Path -path $ScriptDirectory) -ne $True)
{
     #Throw an error of some kind (the parameter passed in isn't a valid directory).
}

$Minifier = “C:\Program Files\Microsoft\Microsoft Ajax Minifier 4\AjaxMin.exe”

get-childitem $ScriptDirectory -recurse -force -include *.js, *.css -exclude *.min.js, *.min.css | foreach-object {&$Minifier $_.FullName -out $_.FullName -clobber}

因此,我们遍历根文件夹的每个子项目,扩展名为.js或.css(忽略.min。*的扩展名,因为这些已被压缩)。

在TFS中,我们需要做的就是向execute the PowerShell script in TFS添加InvokeProcess步骤。您可以使用InvokeProcess活动的Arguments属性传递您的参数(开始minifiying的目录)。

要获取TFS构建用于在代码发布之前编译代码的目录(临时工作空间,如果您愿意),您可以在构建的Run On Agent序列中使用可用的SourcesDirectory变量。这是您的文件由TFS构建过程编译和打包的位置,因此在此处缩小的任何内容都将在最终部署包中结束。

P.S - SourcesDirectory非常高 - 你可能不想从那里一直钻到你的.js和.css文件,所以你需要指定类似的东西:

SourcesDirectory + "/" + "MyProjectFolder/Scripts"

确保在代码部署到工作流之前添加此InvokeProcess步骤并且hey-presto - 您将拥有缩小的.js和.css文件,这些文件仅将原始文件名保留为TFS构建的一部分而不是当地人。

非常感谢所有回答并指出我正确方向的人。我希望这可以帮助一路上的人!

答案 1 :(得分:1)

将此作为自定义代码活动肯定是可行的,但您必须付出一些努力。我的建议是:

  1. 首先关注Ewald Hofman在http://www.ewaldhofman.nl/post/2010/04/29/Customize-Team-Build-2010-e28093-Part-4-Create-your-own-activity.aspx的TFS 2010自定义博客,了解创建自定义活动的内容
  2. 然后从同一系列中查看http://www.ewaldhofman.nl/post/2010/06/01/Customize-Team-Build-2010-e28093-Part-10-Include-Version-Number-in-the-Build-Number.aspx以实现一种机制来查找符合某种模式的所有文件。在该示例中,assemblyInfo.cs文件已编制索引并且其内容已更改。通过搜索* .js文件替换它。
  3. 在文件选择上释放Ajax Minifier的强大功能,并用缩小的文件替换原始文件。
  4. 构建活动,将其作为您在TFS 2010中使用的构建过程模板中的一个步骤(也在相同的博客文章中描述)并将其微调到您对其满意的程度。
  5. 或者,您可以询问您在问题中包含的帖子的作者,以分享他与我们一起创建的Minifier TFS活动: - )

    请让我知道这对你有什么帮助。

答案 2 :(得分:1)

您需要实现Invoke Process Activity,以便在TFS构建期间执行Minifier。

为此,您还必须在构建服务器的服务器中安装minifier,因此所谓的Build-Agent(s)。通过这样做,您将确保仅在TFS构建期间调用Minifier(而不是本地VS-Build)。

为了重命名生成的输出文件(* .min.js),您需要为此实现另一个自定义活动。 覆盖签入的文件需要先让它们写入,这意味着另一个自定义活动(我在another answer中提供了一个代码片段。)

整个编舞是 使用InvokeProcess调用Minifier - > 签入可写文件 - > 使用重命名的缩小文件覆盖已检入的文件

在TFS构建中执行此操作的正确方法是将它们包装在Sequence中。

有关如何实施调用流程的好的介绍性博客文章可以找到here 我还发现E.Hofman的series具有实际价值。