Aug 23, 2010

Cleaning up pre-compiled web deployables

Have your .NET Web Application projects been breaking the scale when it comes time to deploy? Chances are, you might be including a lot of unnecessary files. Unlike our own guts, it's pretty easy for .NET projects to lose that beer belly. Plus, it's really simple to add the step.

Where I work, we use the Microsoft-provided Web Deployment projects (2005, 2008, 2010). The added performance and security make it a no brainer and it isn't difficult at all to drop in to even existing projects. The pre-compilation step is near automatic once you have your build settings all set up. There are plenty of guides on how to use these great and simple projects, so I won't go into them here. One extra step we've taken, though, is to clean-up the output of the deployment project.

Prod likes it lean

Production environments generally have no need for project files, XML documentation, debug symbols, empty folders (particularly if you store related CS files in a folder, this will after compilation leave them empty). Even with pre-compilation, these files can and will be included. They don't hurt anything, but they could be a security concern and furthermore they're unnecessary clutter! I like clean installs, don't you?

Configuring the deployment project to do it for you

While there are a number of solutions you could probably cook up to remove these files, including the ol' fashioned Explorer shell shift-delete way, but as for me I prefer to let it happen as part of the normal build/deploy process. Web deployment projects have a number of advanced features not directly exposed by the little property sheet GUI you normally work with (this is because they are basically a nice frontend to the much more powerful but command-line driven msbuild).

To get started, make sure your deployment project is unloaded. Once it is, you can right-click it and get a new option to Edit the deployment project file directly (Edit *.wdproj). You'll be greeted by a bunch of XML — shouldn't be at all surprising at this point when working with Microsoft developer stuff.

About halfway down, you should find a section called <ItemGroup>, which for you will probably be empty. This section typically appears after the various PropertyGroup sections.

By adding <ExcludeFromBuild> lines (as many as you need), you can have it do just that: exclude files from the output! It works basically by defining a matching search string. Think of it like file matching you could do in DOS or via an Open File dialog. You got your * wildcard and you can match by folder location, partial file name matching, or by extension. Here's a typical example we use to exclude debug symbols, XML documentation, and misc project files:
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\bin\*.pdb">
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\bin\*.xml">
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.svn">
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.csproj">
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.user">
    <ExcludeFromBuild Include="$(SourceWebPhysicalPath)\**\*.vspscc">
Notice the folder matching. We remove PDBs and XML files from the bin folder and all else from the root.

Empty folders take a bit more work

What about removing entire folders? We can do that, too! Typically, you won't need your empty Properties folder or anything in the obj folder for production purposes. To our same ItemGroup section as above, add lines like the following to remove entire folders:
    <RemoveAfterBuild Include="$(OutputPath)\obj\">
    <RemoveAfterBuild Include="$(OutputPath)\Properties\">
You have to do one more step, though, to get the RemoveAfterBuild lines to work. Near the bottom of the project file should be a series of commented-out Target sections. These are for "events" of sorts. The one we want is the last one, AfterBuild. Uncomment it and make it look like this:
  <Target name="AfterBuild">
    <RemoveDir Directories="@(RemoveAfterBuild)">
Now it'll remove those folders for you after building!

Hopefully your manager will notice how your deployables have been losing weight.


Be careful not to trim too much fat. Marker files, despite being nothing more than an 86 byte file containing a single sentence, are there for a reason. Do you really think Microsoft would have generated and left them there if they weren't needed? IIS needs to see those markers or it gets confused when grabbing virtual file paths. (You are testing your deployments after removing all these files, aren't you?)

No comments:

Post a Comment