I have a few goals I'd like to achieve but I'm unsure of how to get there:
From this article:
http://encosia.com/automatically-minify-and-combine-javascript-in-visual-studio/
I've added JSMin to minify my files using a command like this:
"$(SolutionDir)Tools\jsmin.exe" < "$(ProjectDir)Scripts\myfile.js" > "$(ProjectDir)Scripts\myfile.min.js"
I'll also be adding this to my web pages for preserving non-minified files during debug mode:
<% if (HttpContext.Current.IsDebuggingEnabled) { %>
<script type="text/javascript" src="scripts\myfile.js"></script>
<% } else { %>
<script type="text/javascript" src="scripts/myfile.min.js"></script>
<% } %>
So really I'm left with trying to figure out how to prevent myfile.min.js being seen as static content by a web browser when it is updated. If my goal wasn't single-click deployment I could just add a version number manually, but that doesn't seem like a solid approach. Thoughts?
This answer is a little late, but I think it's a fairly solid approach to making sure the caching behavior is in sync with the file, based on a checksum of the file itself.
<script type="text/javascript" src="/Scripts/Scripts.min.js?v=<%= Utils.GetFileHash("/Scripts/Scripts.min.js") %>"></script>
And in your Utils class, you have the method that generates the checksum of the file
public static string GetFileHash(string path)
{
string hash = (string)HttpContext.Current.Cache["_hash_" + path];
if (hash == null)
{
// Get the physical path of the file
string file = HttpContext.Current.Server.MapPath(path);
// Code for MD5 hashing omitted for brevity
hash = Utils.GetMD5(file);
// Insert the hash into the Cache, with a dependency on the underlying file
HttpContext.Current.Cache.Insert("_hash_" + path, hash, new System.Web.Caching.CacheDependency(file));
}
return hash;
}
This caches the hash of the file, so it only needs to calculate it whenever the file changes.
Also, the CacheDependency ensures that if you were to change your .js file, it would make sure the hash gets regenerated.
Hope this helps, it's what I'm using in one of my production websites.
Rather than littering your source code with if/else
all over the place, you might consider implementing an IHttpFilter
that does the minification on-the-fly. Something like what this article does should work nicely.
Your javascript should be cacheable, and the overhead of minification on the webserver will be minimal. Implementing it as an IHttpFilter
also means you don't have to add routes or change existing URLs, and you can add the IHttpFilter
conditionally only in your release configuration so you can still debug your javascript during development.
As for versioning, an HTML helper (here's a link with some more info) would solve the problem nicely by tacking on the version number as a query string parameter. You could even go so far as to have your debug version of the IHttpFilter
throw an exception if the version parameter doesn't exist, so you have something to remind you to use the HTTP helper whenever you add a new javascript file.
I think I have a relatively suitable answer, but feedback would be much appreciated:
script type="text/javascript" src='@Url.Content("~/Scripts/myfile.min.js?v=" + typeof(MyProject.Web.Controllers.MyController).Assembly.GetName().Version.ToString())'
Thoughts on this approach?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With