在Visual Studio 2010中使用Microsoft AJAX Minifier一键式发布

时间:2011-02-18 15:58:30

标签: visual-studio-2010 msdeploy microsoft-ajax-minifier

Microsoft AJAX Minifier提供build task,可以在TFS或本地构建定义中使用。

我在本地项目文件(构建到单独的文件)和TFS构建定义(覆盖现有的JS文件)中都巧妙地使用了它。

我想转而使用Visual Studio 2010的一键式发布功能而不是TFS构建定义,但是在项目文件中将缩小任务添加为AfterBuild目标似乎不会影响单击发布特征

使用this threadthese articles中的信息,我尝试在我的WAP根目录中创建一个名为'[ProjectName] .wpp.targets的文件,并使用以下XML:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\Microsoft\MicrosoftAjax\ajaxmin.tasks" />
<Target Name="Minify" BeforeTargets="MSDeployPublish">
    <ItemGroup>
      <JS Include="**\*.js" Exclude="**\*.min.js;**\*vsddoc.js;**\*debug.js" />
    </ItemGroup>
    <ItemGroup>
      <CSS Include="**\*.css" Exclude="**\*.min.css" />
    </ItemGroup>
    <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js" CssSourceFiles="@(CSS)" CssSourceExtensionPattern="\.css$" CssTargetExtension=".min.css" />
  </Target>
</Project>

这似乎没有任何效果,不幸的是,Visual Studio对这些工具的反馈或调试信息没有太多帮助。

有没有人使用Visual Studio 2010一键发布功能来缩小JavaScript / CSS?

2 个答案:

答案 0 :(得分:22)

我刚刚写了一篇关于如何做到这一点的详细博客文章 http://sedodream.com/2011/02/25/HowToCompressCSSJavaScriptBeforePublishpackage.aspxhttp://blogs.msdn.com/b/webdevtools/archive/2011/02/24/how-to-compress-css-javascript-before-publish-package.aspx

以下是内容

今天我在stackoverflow.com上看到一篇帖子,要求使用Microsoft AJAX Minifier和Visual Studio 2010一键发布。这是对这个问题的回应。 Web Publishing Pipeline非常广泛,因此我们很容易将其挂钩以执行这些操作。其中一个扩展点,正如我们之前发表的博客,正在创建一个.wpp.targets文件。如果在项目的同一目录中使用名称{ProjectName} .wpp.targets创建文件,则该文件将自动导入并包含在构建/发布过程中。这样可以轻松编辑构建/发布过程,而无需始终编辑项目文件。我将使用这种技术来演示如何压缩CSS&amp;项目在发布/打包之前包含的JavaScript文件。

尽管问题明确指出Microsoft AJAX Minifier我决定使用Packer.NET中包含的压缩器(资源部分中的链接)。我这样做是因为当我查看AJAX Minifier的MSBuild任务时,它看起来不像我可以控制压缩文件的输出位置。相反,它只是用.min.cs或.min.js这样的扩展名写入同一个文件夹。在任何情况下,当您发布/打包Web应用程序项目(WAP)时,文件将在发布/包发生之前复制到临时位置。此位置的默认值为obj {Configuration} \ Package \ PackageTmp \,其中{Configuration}是您当前用于WAP的构建配置。所以我们需要做的是允许WPP将所有文件复制到该位置,然后我们可以压缩该文件夹中的CSS和JavaScript。将文件复制到该位置的目标是CopyAllFilesToSingleFolderForPackage。 (要了解有关这些目标的更多信息,请查看文件%Program Files(x86)%\ MSBuild \ Microsoft \ VisualStudio \ v10.0 \ Web \ Microsoft.Web.Publishing.targets。)使目标在此目标之后运行我们可以使用MSBuild AfterTargets属性。我为展示这个而创建的项目叫做CompressBeforePublish,因为我创建了一个名为CompressBeforePublish.wpp.targets的新文件来包含我的更改。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <UsingTask TaskName="SmallSharpTools.Packer.MSBuild.Packer"
             AssemblyFile="$(MSBuildThisFileDirectory)..\Contrib\SmallSharpTools.Packer\SmallSharpTools.Packer.dll" />

  <!-- This target will run after the files are copied to PackageTmp folder -->
  <Target Name="CompressJsAndCss" AfterTargets="CopyAllFilesToSingleFolderForPackage">
    <!-- Discover files to compress -->
    <ItemGroup>
      <_JavaScriptFiles Include="$(_PackageTempDir)\Scripts\**\*.js" />
      <_CssFiles Include="$(_PackageTempDir)\Content\**\*.css" />
    </ItemGroup>

    <Message Text="Compressing JavaScript files" Importance="high" />
    <!-- 
      Compress the JavaScript files. 
      Not the usage of %(JavaScript.Identity which causes this task to run once per
      .js file in the JavaScriptFiles item list.
      For more info on batching: http://sedotech.com/resources#Batching
    -->
    <Packer InputFiles="%(_JavaScriptFiles.Identity)"
            OutputFileName="@(_JavaScriptFiles->'$(_PackageTempDir)\Scripts\%(RecursiveDir)%(Filename)%(Extension)')"
            Mode="JSMin"
            Verbose="false"
            Condition=" '@(_JavaScriptFiles)' != ''" />

    <Message Text="Compressing CSS files" Importance="high" />

    <Packer InputFiles="%(_CssFiles.Identity)"
            OutputFileName="@(_CssFiles->'$(_PackageTempDir)\Content\%(RecursiveDir)%(Filename)%(Extension)')"
            Mode="CSSMin"
            Verbose="false"
            Condition=" '@(_CssFiles)' != '' "/>
  </Target>
</Project>

这里我创建了一个目标CompressJsAndCss,并且我已经包含了AfterTargets =“CopyAllFilesToSingleFolderForPackage”,这使得它在CopyAllFilesToSingleFolderForPackage之后执行。在这个目标里面,我做了两件事,收集需要压缩的文件然后压缩它们。

<强> 1。收集要压缩的文件

<ItemGroup>
  <_JavaScriptFiles Include="$(_PackageTempDir)\Scripts\**\*.js" />
  <_CssFiles Include="$(_PackageTempDir)\Content\**\*.css" />
</ItemGroup>

这里我使用JavaScript文件和CSS文件的项目列表。请注意,我使用_PackageTempDir属性来拾取.js&amp; .css文件位于写入文件的临时文件夹中以进行打包。之所以我这样做而不是选择源文件是因为我的构建可能正在输出其他.js&amp; .css文件以及将要发布的文件。注意:由于属性_PackageTempDir以下划线开头,因此无法保证在将来的版本中表现(甚至存在)。

<强> 2。压缩文件

我使用Packer任务来压缩.js和.css文件。对于这两组文件,使用情况非常相似,所以我只看第一次使用。

<Packer InputFiles="%(_JavaScriptFiles.Identity)"
        OutputFileName="@(_JavaScriptFiles->'$(_PackageTempDir)\Scripts\%(RecursiveDir)%(Filename)%(Extension)')"
        Mode="JSMin"
        Verbose="false"
        Condition=" '@(_JavaScriptFiles)' != ''" />

这里任务被送入所有.js文件进行压缩。请注意我是如何使用%(_ JavaScriptFiles.Identity)将文件传递给任务的,在这种情况下,这样做是为了使每个.js文件执行一次此任务。 %(abc.def)语法调用批处理,如果您不熟悉批处理,请参阅下文。对于输出文件的值,我再次使用_PackageTempDir属性。在这种情况下,因为项目已经存在于那里,我可以将其简化为@(_ JavaScriptFiles-&gt;'%(FullPath)')但我认为您可能会发现该表达式在您压缩尚未存在的文件时很有用存在于_PackageTempDir文件夹中。

现在我们已将此目标添加到.wpp.targets文件中,我们可以发布/打包我们的Web项目,并将其包含在.js&amp; .css文件将被压缩。注意:每当修改.wpp.targets文件时,您都必须卸载/重新加载Web项目,以便获取更改,Visual Studio会缓存您的项目。

在下图中,您可以看到压缩这些文件的区别。 enter image description here

您可以在下面下载整个项目,也可以查看我可能感兴趣的其他一些资源。

<强>资源

答案 1 :(得分:0)

为了在2015年的Visual Studio中工作,我们必须改变&#34; AfterTarget&#34;从

<Target Name="CompressJsAndCss" AfterTargets="CopyAllFilesToSingleFolderForPackage">

以下

<Target Name="CompressJsAndCss" AfterTargets="PipelineCopyAllFilesToOneFolderForMsdeploy">

享受!!