我刚刚在http://sedodream.com/2011/02/25/HowToCompressCSSJavaScriptBeforePublishpackage.aspx和http://blogs.msdn.com/b/webdevtools/archive/2011/02上写了一篇关于如何做到这一点的详细博客文章
/24/how-to-compress-css-javascript-before-publish-package.aspx。
以下是内容
今天我在 stackoverflow.com 上看到一篇帖子,询问 Using Microsoft AJAX Minifier with Visual Studio 2010 1-click publish。这是对那个问题的回应。Web Publishing Pipeline 非常广泛,因此我们很容易连接到它以执行诸如此类的操作。正如我们之前在博客中提到的,其中一个扩展点是创建一个 .wpp.targets 文件。如果您在项目的同一目录中创建一个名为 {ProjectName}.wpp.targets 的文件,那么该文件将自动导入并包含在构建/发布过程中。这使得编辑构建/发布过程变得容易,而不必总是编辑项目文件本身。我将使用这种技术来演示如何在项目发布/打包之前压缩项目包含的 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 的新文件来包含我的更改。(要了解有关这些目标的更多信息,请查看文件 %Program Files (x86)%\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets。)要使我们的目标在此目标之后运行我们可以使用 MSBuild AfterTargets 属性。我为演示这一点而创建的项目称为 CompressBeforePublish,因为我创建了一个名为 CompressBeforePublish.wpp.targets 的新文件来包含我的更改。(要了解有关这些目标的更多信息,请查看文件 %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 和 .css 文件。我这样做而不是拾取源文件的原因是因为我的构建可能正在输出其他 .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 和 .css 文件将被压缩。注意:无论何时修改 .wpp.targets 文件,您都必须卸载/重新加载 Web 项目,以便获取更改,Visual Studio 会缓存您的项目。
在下图中,您可以看到压缩这些文件的不同之处。
您可以在下面下载整个项目,也可以查看我拥有的您可能感兴趣的其他一些资源。
资源