将 Microsoft AJAX Minifier 与 Visual Studio 2010 一键发布结合使用

发布于 2024-10-18 02:30:30 字数 1662 浏览 8 评论 0原文

Microsoft AJAX Minifier 提供了 构建任务 可以在 TFS 或本地构建定义中使用。

我已经在本地项目文件(构建为单独的文件)和 TFS 构建定义(覆盖现有的 JS 文件)中成功地使用了它。

我想转而使用 Visual Studio 2010 的一键发布功能而不是 TFS 生成定义,但是将缩小任务添加为项目文件中的 AfterBuild 目标似乎不会影响一键发布功能。

使用此帖子这些 文章,我尝试在 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 吗?

The Microsoft AJAX Minifier provides a build task which can be used in TFS or local build definitions.

I have succsfully used this in both a local project file (building to seperate files) and in TFS build definitions (overwriting the existing JS files).

I'd like to move to using Visual Studio 2010's 1-click publish feature rather than a TFS build definition, however adding the minification task as an AfterBuild target in the project file doesn't appear to effect the 1-click publish feature.

Using information found in this thread and these articles, I tried creating a file named '[ProjectName].wpp.targets in my WAP root directory, and used the following 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>

This doesn't appear to have any effect, and unfortunately Visual Studio doesn't give much in the way of feedback or debugging info for these tools.

Has anyone had any success minifying JavaScript / CSS using the Visual Studio 2010 1-click publish feature?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

栀梦 2024-10-25 02:30:30

我刚刚写了一篇关于如何执行此操作的详细博客文章,位于
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 1-click 发布。这是对该问题的回应。 Web Publishing Pipeline 非常广泛,因此我们很容易连接到它来执行此类操作。正如我们之前在博客中提到的,这些扩展点之一是创建 .wpp.targets 文件。如果您在项目的同一目录中创建一个名为 {ProjectName}.wpp.targets 的文件,那么该文件将自动导入并包含在构建/发布过程中。这使得编辑构建/发布过程变得容易,而不必总是编辑项目文件本身。我将使用这种技术来演示如何压缩 CSS 和 CSS。项目在发布/打包之前包含的 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 和 .js 文件。写入要打包的文件的临时文件夹内的 .css 文件。我这样做而不是获取源文件的原因是因为我的构建可能会输出其他 .js 和 .js 文件。 .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->'%(FullPath)') 但我认为您可能会发现该表达式在您正在压缩尚未压缩的文件的情况下很有用存在于 _PackageTempDir 文件夹中。

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

在下图中,您可以看到压缩这些文件所产生的差异。
在此处输入图像描述

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

资源

I just wrote a detailed blog entry on how to do this at
http://sedodream.com/2011/02/25/HowToCompressCSSJavaScriptBeforePublishpackage.aspx and http://blogs.msdn.com/b/webdevtools/archive/2011/02/24/how-to-compress-css-javascript-before-publish-package.aspx.

Here are the contents

Today I saw a post on stackoverflow.com asking Using Microsoft AJAX Minifier with Visual Studio 2010 1-click publish. This is a response to that question. The Web Publishing Pipeline is pretty extensive so it is easy for us to hook in to it in order to perform operation such as these. One of those extension points, as we’ve blogged about before, is creating a .wpp.targets file. If you create a file in the same directory of your project with the name {ProjectName}.wpp.targets then that file will automatically be imported and included in the build/publish process. This makes it easy to edit your build/publish process without always having to edit the project file itself. I will use this technique to demonstrate how to compress the CSS & JavaScript files a project contains before it is published/packaged.

Eventhough the question specifically states Microsoft AJAX Minifier I decided to use the compressor contained in Packer.NET (link in resources section). I did this because when I looked at the MSBuild task for the AJAX Minifier it didn’t look like I could control the output location of the compressed files. Instead it would simply write to the same folder with an extension like .min.cs or .min.js. In any case, when you publish/package your Web Application Project (WAP) the files are copied to a temporary location before the publish/package occurs. The default value for this location is obj{Configuration}\Package\PackageTmp\ where {Configuration} is the build configuration that you are currently using for your WAP. So what we need to do is to allow the WPP to copy all the files to that location and then after that we can compress the CSS and JavaScript that goes in that folder. The target which copies the files to that location is CopyAllFilesToSingleFolderForPackage. (To learn more about these targets take a look at the file %Program Files (x86)%\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets.) To make our target run after this target we can use the MSBuild AfterTargets attribute. The project that I created to demonstrate this is called CompressBeforePublish, because of that I create a new file named CompressBeforePublish.wpp.targets to contain my changes.

<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>

Here I’ve created one target, CompressJsAndCss, and I have included AfterTargets=”CopyAllFilesToSingleFolderForPackage” which causes it to be executed after CopyAllFilesToSingleFolderForPackage. Inside this target I do two things, gather the files which need to be compressed and then I compress them.

1. Gather files to be compressed

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

Here I use an item list for both JavaScript files as well as CSS files. Notice that I am using the _PackageTempDir property to pickup .js & .css files inside the temporary folder where the files are written to be packaged. The reason that I’m doing that instead of picking up source files is because my build may be outputting other .js & .css files and which are going to be published. Note: since the property _PackageTempDir starts with an underscore it is not guaranteed to behave (or even exist) in future versions.

2. Compress files

I use the Packer task to compress the .js and .css files. For both sets of files the usage is pretty similar so I will only look at the first usage.

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

Here the task is fed all the .js files for compression. Take a note how I passed the files into the task using, %(_JavaScriptFiles.Identity), in this case what that does is to cause this task to be executed once per .js file. The %(abc.def) syntax invokes batching, if you are not familiar with batching please see below. For the value of the output file I use the _PackageTempDir property again. In this case since the item already resides there I could have simplified that to be @(_JavaScriptFiles->’%(FullPath)’) but I thought you might find that expression helpful in the case that you are compressing files which do not already exist in the _PackageTempDir folder.

Now that we have added this target to the .wpp.targets file we can publish/package our web project and it the contained .js & .css files will be compressed. Note: Whenever you modify the .wpp.targets file you will have to unload/reload the web project so that the changes are picked up, Visual Studio caches your projects.

In the image below you can see the difference that compressing these files made.
enter image description here

You can download the entire project below, as well as take a look at some other resources that I have that you might be interested in.

Resources

梦在深巷 2024-10-25 02:30:30

为了使其在 Visual Studio 2015 中工作,我们必须将“AfterTarget”从更改为

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

以下

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

享受!

For this to work in visual studio 2015, we have to change the "AfterTarget" from

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

to the following

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

enjoy!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文