Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to minify JavaScript files that have changed (and only them) when building (aka duplicate items after adding "ItemGroup" to csproj)

I've added the following code to my .csproj in order to minify the JS files that have changed when building the project:

<Target Name="BeforeBuild">
  <MSBuild Targets="CheckAndMinifyJS" Projects="$(MSBuildProjectFile)" />
</Target>
<ItemGroup>
  <JS Include="$(ProjectDir)\**\*.js" />
</ItemGroup>
<Target Name="CheckAndMinifyJS" Inputs="@(JS)" Outputs="@(JS->'$(ProjectDir)%(RecursiveDir)%(Filename).min.js')">
  <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js" />
</Target>
<UsingTask TaskName="AjaxMin" AssemblyFile="..\..\ThirdParty\AjaxMinTask.dll" />

This works great, but it has a side effect: when you look at the project in Visual Studio (2015), all the JS files appear duplicated (same path, but different build action):

Duplicate items

I would like to avoid having the item with "JS" build action appearing in the project. How can I do that?

Please note that the several developers are working with the project, so any proposed solution should be contained within the .csproj or the solution (eg: it is not acceptable to ask all developers to modify their registry to change the default build action for JS files).

like image 630
Gyum Fox Avatar asked Nov 10 '22 07:11

Gyum Fox


1 Answers

To hide your ItemGroup from Visual Studio, move it into an intermediate Target. In addition to that change, the following code filters the existing Content items rather than recursing the file system again. This ensures you don't pick up extraneous .js files (for example intermediate output files in obj\, or .min.js files generated by your script but not explicitly added to the project).

  <Target Name="BeforeBuild">
    <MSBuild Targets="CheckAndMinifyJS" Projects="$(MSBuildProjectFile)" />
  </Target>
  <Target Name="GetJSItems" BeforeTargets="CheckAndMinifyJS">
    <ItemGroup>
      <JS Include="@(Content)" Condition=" '%(Extension)' == '.js' " />
    </ItemGroup>
  </Target>
  <Target Name="CheckAndMinifyJS" Inputs="@(JS)" Outputs="@(JS->'$(ProjectDir)%(RecursiveDir)%(Filename).min.js')">
    <AjaxMin JsSourceFiles="@(JS)" JsSourceExtensionPattern="\.js$" JsTargetExtension=".min.js" />
  </Target>
  <UsingTask TaskName="AjaxMin" AssemblyFile="..\..\ThirdParty\AjaxMinTask.dll" />
like image 94
weir Avatar answered Nov 15 '22 05:11

weir