1

I am using the Microsoft Ajax Minifier to minify my javascript files. In the manifest, I would like to specify that all js files in a source folder should be minified into a different output folder. The original filename should be used as the output filename plus a variable should be appended. I would like to do something like the manifest below where the output uses a * wildcard and the variable is a version number of 4.60.

<?xml version="1.0" encoding="utf-8"?>
$(version) = "-4.60"
<root>
    <output path="..\Scripts\Pages\*$(version)" type="js">
        <input path="Scripts\PageSource\" type="js" />
    </output>
</root>

Using a * in the output setting throws a build error but maybe there is a different wildcard character? There are a lot of output and input settings, which is why I'd like to specify a version number once and reuse it.

Could any of the settings in the targets file (see below) be used for this purpose? I could not find any examples that show what the ProjectDefaultSwitches and Configuration settings do.

<!-- target to build all ajaxmin manifest files in the project -->
<Target Name="BuildAjaxMinManifests" AfterTargets="Build">
    <Message Text="Processing AjaxMin Manifests" Importance="high" />
    <CreateItem Include="@(None)" Condition="'%(Extension)'=='.ajaxmin'">
        <Output TaskParameter="Include" ItemName="AjaxMinManifests"/>
    </CreateItem>

    <AjaxMinManifestTask ProjectDefaultSwitches="-define:$(DefineConstants))"
                         Configuration="$(Configuration)"
                         TreatWarningsAsErrors="false"
                         InputFolder="$(ProjectDir)"
                         OutputFolder="$(ProjectDir)Content\"
                         Manifests="@(AjaxMinManifests)" />
</Target>

Is this possible?

ESS
  • 175
  • 1
  • 15

2 Answers2

1

The documentation for the AjaxMinTask has examples which do exactly what you're after: list the input files and minify to a new filename based on it. Something like this:

<!-- This should point to the dll, or check docs and alternatively use 'Import'-->
<UsingTask TaskName="AjaxMin" AssemblyFile="$(MSBuildProjectDirectory)\AjaxMinTask.dll" />

<Target Name="Minify" AfterTargets="Build">
  <PropertyGroup>
    <!-- Version number to append should be defined somewhere -->
    <MinVersion>4.60</MinVersion>
  </PropertyGroup>
  <ItemGroup>
    <!-- List the input files, assume relative to project file -->
    <ToMinify Include="$(MSBuildProjectDirectory)\Scripts\PageSource\*.js"/>
  </ItemGroup>
  <!-- Minify -->
  <AjaxMin JsSourceFiles="@(ToMinify)" JsSourceExtensionPattern="\.js$" JsTargetExtension="..\Page\$(MinVersion).js"/>
</Target>

Paste this somewhere near the end of the project file and the AfterTargets="Build" part will make this target run automatically after a build.

The AjaxMinManifestTask might be usable as well but it doesn't seem to have options to alter filenames. Still you could use it and after it and rename all files to include the version number but that's just extra work. Another alternative is to use msbuild logic to list source/destination files and then minify them individualy using the executble. Might be slower, just adding this for completeness:

<Target Name="Minify" AfterTargets="Build">
  <PropertyGroup>
    <MinVersion>4.60</MinVersion>
  </PropertyGroup>
  <ItemGroup>
    <ToMinify Include="$(MSBuildProjectDirectory)\Scripts\PageSource\*.js"/>
  </ItemGroup>
  <Exec Command="ajaxmin.exe %(ToMinify.Identity) -out $(MSBuildProjectDirectory)\Script\Pages\%(ToMinify.FileName)$(MinVersion).jsmin -clobber" />
</Target>
stijn
  • 34,664
  • 13
  • 111
  • 163
  • Thanks for replying @stijn but I've read all of the [AjaxMinTask docs](http://ajaxmin.codeplex.com/documentation) and do not see any examples of using a PropertyGroup for a version number. After adjusting pathing, I added your 1st settings at the bottom of my .vbproj file but got an error since the dll is not within our project. Even so, I'd rather not have to unload & edit the project file for every version number change. Also, nothing happened when I added your 2nd settings after the – ESS Dec 21 '16 at 18:50
  • Regarding version number: if you don't want it in the main project, put it in a seperate one which you Import. Or read it from a text file or so, or from a git tag, or... (none of this is AjaxMin specific, it's just msbuild). If you don't want to hardoce the path to the dll you can use instead, see docs. – stijn Dec 21 '16 at 19:11
  • *nothing happened when I added your 2nd settings after the – stijn Dec 21 '16 at 19:13
  • Now I installed from MSI. I still need .targets for different files that combine into 1 .js and .css. For 2nd, files exist in source. Are you sure – ESS Dec 21 '16 at 20:25
  • Are you sure "%(ToMinify.FileName)$(MinVersion)" is correct? – ESS Dec 21 '16 at 20:26
  • Thanks @stijn but the 1st approach won't work because there is no jsTargetPath parameter. You can't "fake" a target location with JsTargetExtension because the entire source path and filename is used for the new file. The JsTargetExtension value is just appended to the end. I have not gotten the 2nd approach to work either. – ESS Dec 21 '16 at 21:57
0

So far it appears that it is not possible to use wildcards and variables in the manifest files but I was able to accomplish my overall goal by using the second approach that @stijn suggested. Here is what I did:

  1. Downloaded and installed the Microsoft Ajax Minifier
  2. Located the installation folder and copied the AjaxMin.dll, AjaxMin.exe, AjaxMinifier.exe, and AjaxMinTask.dll files into the Build folder of the project. If there is more than one developer then this folder should be under source control.
  3. Created a file called AjaxMin.targets in the Build folder of the project. The contents of the file is:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <UsingTask TaskName="AjaxMinManifestTask" AssemblyFile="$(ProjectDir)Build\AjaxMinTask.dll" /> <Target Name="BuildAjaxMinManifests" AfterTargets="Build"> <Message Text="Processing Manifest" Importance="high" /> <CreateItem Include="@(None)" Condition="'%(Extension)'=='.ajaxmin'"> <Output TaskParameter="Include" ItemName="AjaxMinManifests"/> </CreateItem> <AjaxMinManifestTask ProjectDefaultSwitches="-define:$(DefineConstants)" Configuration="$(Configuration)" TreatWarningsAsErrors="false" InputFolder="$(ProjectDir)" OutputFolder="$(ProjectDir)" Manifests="@(AjaxMinManifests)" /> <Message Text="Processing Pages" Importance="high" /> <PropertyGroup> <VerNumber>4-62-0-0</VerNumber> </PropertyGroup> <ItemGroup> <ToMinify Include="$(ProjectDir)Scripts\PageSource\*.js"/> </ItemGroup> <Exec Command="$(ProjectDir)Build\AjaxMin.exe %(ToMinify.Identity) -out $(ProjectDir)Scripts\Pages\%(ToMinify.FileName)-$(VerNumber).js -clobber" /> </Target> </Project>

  1. Unloaded and then edited the project to add the following at the bottom:

<Import Project="$(MSBuildProjectDirectory)\Build\AjaxMin.targets" />

  1. Made sure the Scripts\PageSource files and Scripts\Pages folder existed.
  2. Closed and reopened the solution.
  3. Rebuilt the solution.

TIP: It seems that changes to the AjaxMin.targets file are not recognized until the solution is reopened. I wasted an entire day going down rabbit holes until I figured this out.

The AjaxMinManifestTask portion of the AjaxMin.targets file kicks off a minification and consolidation of a number of js and css files according to a manifest. The format of the manifest XML is documented at the Microsoft Ajax Minifier website.

The Processing Pages portion of the AjaxMin.targets file kicks off a minification of every file in the Scripts\PageSource folder and outputs the result to the Scripts\Pages folder. It also appends the VerNumber value to the resulting filename.

ESS
  • 175
  • 1
  • 15