In my earlier article about Optimizing without drawbacks I talked about how you can leverage the new optimization and bundling tool without creating caching issues or setting up alot of stuff for it to work.
While bundling and minification are great, under development it can be pain to debug minified files. I've created three simple files that skips the minification process and leaves the structure intact. The last one is an updated version of the css bundler that include images tagget with ?embed as base64 strings.
PlainJsBundler.cs
public class PlainJsBundler : IBundleTransform
{
public virtual void Process(BundleResponse bundle)
{
bundle.ContentType = "text/javascript";
}
}PlainCssBundler.cs
public class PlainCssBundler : IBundleTransform
{
public virtual void Process(BundleResponse bundle)
{
bundle.ContentType = "text/css";
}
}PlainCssWithImagesBundler.cs
public class PlainCssWithImagesBundler : PlainCssBundler
{
private static readonly Regex url = new Regex(@"url\((([^\)]*)\?embed)\)", RegexOptions.Singleline);
private const string format = "url(data:image/{0};base64,{1})";
public override void Process(BundleResponse bundle)
{
HttpContext.Current.Response.Cache.SetLastModifiedFromFileDependencies();
base.Process(bundle);
string reference = HttpContext.Current.Request.Path.Replace("/css", "/");
if (reference == "/")
reference = "/Content/";
foreach (Match match in url.Matches(bundle.Content))
{
var file = new FileInfo(HostingEnvironment.MapPath(reference + match.Groups[2].Value));
if (file.Exists)
{
string dataUri = GetDataUri(file);
bundle.Content = bundle.Content.Replace(match.Value, dataUri);
HttpContext.Current.Response.AddFileDependency(file.FullName);
}
}
}
private string GetDataUri(FileInfo file)
{
byte[] buffer = File.ReadAllBytes(file.FullName);
string ext = file.Extension.Substring(1);
return string.Format(format, ext, Convert.ToBase64String(buffer));
}
}By changing our code in global.asax to the following we will now only minify content when we are compiling as Release. The reason I've created a PlainCssWithImagesBundler is to catch possible problems with the images embedded while still being able to read the css.
Application_Start in Global.asax
#if (DEBUG)
var css = new DynamicFolderBundle("css", typeof(PlainCssWithImagesBundler), "*.css");
BundleTable.Bundles.Add(css);
var js = new DynamicFolderBundle("js", typeof(PlainJsBundler), "*.js");
BundleTable.Bundles.Add(js);
#else
var css = new DynamicFolderBundle("css", typeof(CssWithImagesMinify), "*.css");
BundleTable.Bundles.Add(css);
#endif